diff options
116 files changed, 5173 insertions, 366 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 6148ce0..bc607cb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -628,6 +628,7 @@ James Lemke jwlemke <jim@lemke.org> Ilya Leoshkevich iii <iii@linux.ibm.com> Kriang Lerdsuwanakij lerdsuwa <lerdsuwa@users.sourceforge.net> Pan Li - <pan2.li@intel.com> +Pengfei Li pfustc <pengfei.li2@arm.com> Renlin Li renlin <renlin.li@arm.com> Xinliang David Li davidxl <davidxl@google.com> Kewen Lin linkw <linkw@gcc.gnu.org> diff --git a/contrib/download_prerequisites b/contrib/download_prerequisites index b83fcc9..a6d756c 100755 --- a/contrib/download_prerequisites +++ b/contrib/download_prerequisites @@ -27,9 +27,9 @@ version='(unversioned)' # remember to also update the files `contrib/prerequisites.sha512` and # `contrib/prerequisites.md5` with the new checksums. -gmp='gmp-6.2.1.tar.bz2' -mpfr='mpfr-4.1.0.tar.bz2' -mpc='mpc-1.2.1.tar.gz' +gmp='gmp-6.3.0.tar.bz2' +mpfr='mpfr-4.2.2.tar.bz2' +mpc='mpc-1.3.1.tar.gz' isl='isl-0.24.tar.bz2' gettext='gettext-0.22.tar.gz' diff --git a/contrib/prerequisites.md5 b/contrib/prerequisites.md5 index 716a9ff..96b9802 100644 --- a/contrib/prerequisites.md5 +++ b/contrib/prerequisites.md5 @@ -1,5 +1,5 @@ -28971fc21cf028042d4897f02fd355ea gmp-6.2.1.tar.bz2 -44b892bc5a45bafb4294d134e13aad1d mpfr-4.1.0.tar.bz2 -9f16c976c25bb0f76b50be749cd7a3a8 mpc-1.2.1.tar.gz +c1cd6ef33085e9cb818b9b08371f9000 gmp-6.3.0.tar.bz2 +afe8268360bc8702fbc8297d351c8b5e mpfr-4.2.2.tar.bz2 +5c9bc658c9fd0f940e8e3e0f09530c62 mpc-1.3.1.tar.gz dd2f7b78e118c25bd96134a52aae7f4d isl-0.24.tar.bz2 c092102240f8f66134d22718421d5115 gettext-0.22.tar.gz diff --git a/contrib/prerequisites.sha512 b/contrib/prerequisites.sha512 index f71398b..7a3e9c2 100644 --- a/contrib/prerequisites.sha512 +++ b/contrib/prerequisites.sha512 @@ -1,5 +1,5 @@ -8904334a3bcc5c896ececabc75cda9dec642e401fb5397c4992c4fabea5e962c9ce8bd44e8e4233c34e55c8010cc28db0545f5f750cbdbb5f00af538dc763be9 gmp-6.2.1.tar.bz2 -410208ee0d48474c1c10d3d4a59decd2dfa187064183b09358ec4c4666e34d74383128436b404123b831e585d81a9176b24c7ced9d913967c5fce35d4040a0b4 mpfr-4.1.0.tar.bz2 -3279f813ab37f47fdcc800e4ac5f306417d07f539593ca715876e43e04896e1d5bceccfb288ef2908a3f24b760747d0dbd0392a24b9b341bc3e12082e5c836ee mpc-1.2.1.tar.gz +3b684c9bcb9ede2b7e54d0ba4c9764bfa17c20d4f3000017c553b6f1e135b536949580ff37341680c25dc236cfe0ba1db8cfdfe619ce013656189ef0871b89f8 gmp-6.3.0.tar.bz2 +0176e50808dcc07afbf5bc3e38bf9b7b21918e5f194aa0bfd860d99b00c470630aef149776c4be814a61c44269c3a5b9a4b0b1c0fcd4c9feb1459d8466452da8 mpfr-4.2.2.tar.bz2 +4bab4ef6076f8c5dfdc99d810b51108ced61ea2942ba0c1c932d624360a5473df20d32b300fc76f2ba4aa2a97e1f275c9fd494a1ba9f07c4cb2ad7ceaeb1ae97 mpc-1.3.1.tar.gz aab3bddbda96b801d0f56d2869f943157aad52a6f6e6a61745edd740234c635c38231af20bc3f1a08d416a5e973a90e18249078ed8e4ae2f1d5de57658738e95 isl-0.24.tar.bz2 e2a58dde1cae3e6b79c03e7ef3d888f7577c1f4cba283b3b0f31123ceea8c33d7c9700e83de57104644de23e5f5c374868caa0e091f9c45edbbe87b98ee51c04 gettext-0.22.tar.gz diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d975768..b600551 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,223 @@ +2025-08-06 Uros Bizjak <ubizjak@gmail.com> + + PR target/96226 + * config/i386/predicates.md (and_operator): New operator. + * config/i386/i386.md (splitter after *<rotate_insn><mode>3_mask): + Use and_operator to match AND RTX and use its mode + in the split pattern. + +2025-08-06 Gerald Pfeifer <gerald@pfeifer.com> + + PR target/69374 + * doc/install.texi (Prerequisites): Replace bzip2 by xz. + +2025-08-06 Yangyu Chen <cyy@cyyself.name> + + * config/i386/i386.h (PTA_BDVER1): + Add missing PTA_POPCNT and PTA_LZCNT with PTA_ABM. + (PTA_ZNVER1): Ditto. + (PTA_BTVER1): Ditto. + (PTA_LUJIAZUI): Ditto. + (PTA_YONGFENG): Do not include extra PTA_LZCNT. + +2025-08-06 Sam James <sam@gentoo.org> + + PR libstdc++/29286 + * Makefile.in (ALIASING_FLAGS): Drop. + * configure: Regenerate. + * configure.ac: Drop -fno-strict-aliasing workaround for < GCC 4.3. + +2025-08-06 Richard Biener <rguenther@suse.de> + + * tree-vect-data-refs.cc (vect_supportable_dr_alignment): + Prune dead code. + +2025-08-06 Patrick Palka <ppalka@redhat.com> + + PR c++/121231 + PR c++/119688 + PR c++/94511 + * common.opt: Document additional ABI version 21 change. + * doc/invoke.texi: Likewise. + +2025-08-06 Richard Biener <rguenther@suse.de> + + * tree-vectorizer.h (_slp_tree::gs_scale): New. + (_slp_tree::gs_base): Likewise. + (SLP_TREE_GS_SCALE): Likewise. + (SLP_TREE_GS_BASE): Likewise. + (vect_describe_gather_scatter_call): Declare. + * tree-vect-slp.cc (_slp_tree::_slp_tree): Initialize + new members. + (vect_build_slp_tree_2): Record gather/scatter base and scale. + (vect_get_and_check_slp_defs): For gather/scatter IFNs + describe the call to first_gs_info. + * tree-vect-data-refs.cc (vect_gather_scatter_fn_p): Add + mode of operation with fixed offset vector type. + (vect_describe_gather_scatter_call): Export. + * tree-vect-stmts.cc (get_load_store_type): Do not call + vect_check_gather_scatter to fill gs_info, instead populate + from the SLP tree. Check which of, IFN, decl or fallback + is supported and record that decision. + +2025-08-06 Richard Biener <rguenther@suse.de> + + * tree-vect-stmts.cc (vectorizable_store): Build proper + alias + align pointer value for gather/scatter and SLP + and use it. + (vectorizable_load): Likewise. + +2025-08-06 Richard Biener <rguenther@suse.de> + + * tree-vect-stmts.cc (check_load_store_for_partial_vectors): + Remove redundant gather/scatter target support check, instead + check the recorded ifns. Also allow legacy gather/scatter + with loop masking. + +2025-08-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/121413 + * gimple-lower-bitint.cc (gimple_lower_bitint): Fix up last + commit, cast limb_prec to unsigned before comparison. + +2025-08-06 Yang Yujie <yangyujie@loongson.cn> + + * match.pd: Preserve conversion to _BitInt before a VCE + if the _BitInt is extended. + +2025-08-06 Yang Yujie <yangyujie@loongson.cn> + + * gimple-lower-bitint.cc (bitint_large_huge::lower_mergeable_stmt): + Zero-extend the partial limb of any unsigned _BitInt LHS assigned + with a widening sign-extension. + +2025-08-06 Yang Yujie <yangyujie@loongson.cn> + + * gimple-lower-bitint.cc (bitint_large_huge::limb_access): + Add a parameter abi_load_p. If set, load a limb directly + in its actual precision without casting from m_limb_type. + (struct bitint_large_huge): Same. + (bitint_large_huge::handle_load): Use. + +2025-08-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/121413 + * gimple-lower-bitint.cc (abi_limb_prec): New variable + (bitint_precision_kind): Initialize it. + (gimple_lower_bitint): Clear it at the start. For + min_prec > limb_prec descreased precision vars for + INTEGER_CST PHI arguments ensure min_prec is either + prec or multiple of abi_limb_prec. + +2025-08-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/121127 + * gimple-lower-bitint.cc (bitint_large_huge::handle_operand_addr): For + uninitialized SSA_NAME, set *prec_stored to 0 rather than *prec. + Handle that case in narrowing casts. If prec_stored is non-NULL, + set *prec_stored to prec_stored_val. + +2025-08-06 Jakub Jelinek <jakub@redhat.com> + + PR bootstrap/121386 + * Makefile.in (gengtype-lex.cc): Append #define FLEX_SCANNER, + #include "system.h" and #undef FLEX_SCANNER to the prepended lines. + * gengtype-lex.l: Remove inclusion of config.h or bconfig.h, system.h + and definition of malloc/realloc from %{} section. + +2025-08-06 Kito Cheng <kito.cheng@sifive.com> + + * config/riscv/arch-canonicalize: Read extension data from + riscv-ext*.def and adding unittest. + +2025-08-06 Kito Cheng <kito.cheng@sifive.com> + + * common/config/riscv/riscv-common.cc (riscv_expand_arch): + Ignore `unset`. + * config/riscv/riscv.h (OPTION_DEFAULT_SPECS): Handle + `-march=unset`. + (ARCH_UNSET_CLEANUP_SPECS): New. + (DRIVER_SELF_SPECS): Handle -march=unset. + * doc/invoke.texi (RISC-V Options): Update documentation for + `-march=unset`. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * gimplify.cc (remove_unused_omp_iterator_vars): Display unused + variable warning for 'to' and 'from' clauses. + (gimplify_scan_omp_clauses): Add argument for iterator loop sequence. + Gimplify the clause decl and size into the iterator loop if iterators + are used. + (gimplify_omp_workshare): Add argument for iterator loops sequence + in call to gimplify_scan_omp_clauses. + (gimplify_omp_target_update): Call remove_unused_omp_iterator_vars and + build_omp_iterators_loops. Add loop sequence as argument when calling + gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses and building + the Gimple statement. + * tree-pretty-print.cc (dump_omp_clause): Call dump_omp_iterators + for to/from clauses with iterators. + * tree.cc (omp_clause_num_ops): Add extra operand for OMP_CLAUSE_FROM + and OMP_CLAUSE_TO. + * tree.h (OMP_CLAUSE_HAS_ITERATORS): Add check for OMP_CLAUSE_TO and + OMP_CLAUSE_FROM. + (OMP_CLAUSE_ITERATORS): Likewise. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + Andrew Stubbs <ams@baylibre.com> + + * gimple-pretty-print.cc (dump_gimple_omp_target): Print expanded + iterator loops. + * gimple.cc (gimple_build_omp_target): Add argument for iterator + loops sequence. Initialize iterator loops field. + * gimple.def (GIMPLE_OMP_TARGET): Set GSS symbol to GSS_OMP_TARGET. + * gimple.h (gomp_target): Set GSS symbol to GSS_OMP_TARGET. Add extra + field for iterator loops. + (gimple_build_omp_target): Add argument for iterator loops sequence. + (gimple_omp_target_iterator_loops): New. + (gimple_omp_target_iterator_loops_ptr): New. + (gimple_omp_target_set_iterator_loops): New. + * gimplify.cc (find_var_decl): New. + (copy_omp_iterator): New. + (remap_omp_iterator_var_1): New. + (remap_omp_iterator_var): New. + (remove_unused_omp_iterator_vars): New. + (struct iterator_loop_info_t): New type. + (iterator_loop_info_map_t): New type. + (build_omp_iterators_loops): New. + (enter_omp_iterator_loop_context_1): New. + (enter_omp_iterator_loop_context): New. + (enter_omp_iterator_loop_context): New. + (exit_omp_iterator_loop_context): New. + (gimplify_adjust_omp_clauses): Add argument for iterator loop + sequence. Gimplify the clause decl and size into the iterator + loop if iterators are used. + (gimplify_omp_workshare): Call remove_unused_omp_iterator_vars and + build_omp_iterators_loops for OpenMP target expressions. Add + loop sequence as argument when calling gimplify_adjust_omp_clauses + and building the Gimple statement. + * gimplify.h (enter_omp_iterator_loop_context): New prototype. + (exit_omp_iterator_loop_context): New prototype. + * gsstruct.def (GSS_OMP_TARGET): New. + * omp-low.cc (lower_omp_map_iterator_expr): New. + (lower_omp_map_iterator_size): New. + (finish_omp_map_iterators): New. + (lower_omp_target): Add sorry if iterators used with deep mapping. + Call lower_omp_map_iterator_expr before assigning to sender ref. + Call lower_omp_map_iterator_size before setting the size. Insert + iterator loop sequence before the statements for the target clause. + * tree-nested.cc (convert_nonlocal_reference_stmt): Walk the iterator + loop sequence of OpenMP target statements. + (convert_local_reference_stmt): Likewise. + (convert_tramp_reference_stmt): Likewise. + * tree-pretty-print.cc (dump_omp_iterators): Dump extra iterator + information if present. + (dump_omp_clause): Call dump_omp_iterators for iterators in map + clauses. + * tree.cc (omp_clause_num_ops): Add operand for OMP_CLAUSE_MAP. + (walk_tree_1): Do not walk last operand of OMP_CLAUSE_MAP. + * tree.h (OMP_CLAUSE_HAS_ITERATORS): New. + (OMP_CLAUSE_ITERATORS): New. + 2025-08-05 H.J. Lu <hjl.tools@gmail.com> PR target/121410 diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index cf43af9..d4024d7 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20250806 +20250807 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 3406517..cc79595 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -187,8 +187,6 @@ C_STRICT_WARN = @c_strict_warn@ NOEXCEPTION_FLAGS = @noexception_flags@ -ALIASING_FLAGS = @aliasing_flags@ - # This is set by --disable-maintainer-mode (default) to "#" # FIXME: 'MAINT' will always be set to an empty string, no matter if # --disable-maintainer-mode is used or not. This is because the diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index c9ab153..2abe6df 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2025-08-06 Alexandre Oliva <oliva@adacore.com> + + * c-attribs.cc (handle_hardbool_attribute): Create distinct + enumeration types, with structural equality. Handle + base type qualifiers. + 2025-08-02 Martin Uecker <uecker@tugraz.at> * c-attribs.cc (handle_argspec_attribute): Update. diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc index a0d832b..041a004 100644 --- a/gcc/c-family/c-attribs.cc +++ b/gcc/c-family/c-attribs.cc @@ -1128,11 +1128,16 @@ handle_hardbool_attribute (tree *node, tree name, tree args, } tree orig = *node; - *node = build_duplicate_type (orig); + /* Drop qualifiers from the base type. Keep attributes, so that, in the odd + chance attributes are applicable and relevant to the base type, if they + are specified first, or through a typedef, they wouldn't be dropped on the + floor here. */ + tree unqual = build_qualified_type (orig, TYPE_UNQUALIFIED); + *node = build_distinct_type_copy (unqual); TREE_SET_CODE (*node, ENUMERAL_TYPE); - ENUM_UNDERLYING_TYPE (*node) = orig; - TYPE_CANONICAL (*node) = TYPE_CANONICAL (orig); + ENUM_UNDERLYING_TYPE (*node) = unqual; + SET_TYPE_STRUCTURAL_EQUALITY (*node); tree false_value; if (args) @@ -1191,7 +1196,13 @@ handle_hardbool_attribute (tree *node, tree name, tree args, gcc_checking_assert (!TYPE_CACHED_VALUES_P (*node)); TYPE_VALUES (*node) = values; - TYPE_NAME (*node) = orig; + TYPE_NAME (*node) = unqual; + + if (TYPE_QUALS (orig) != TYPE_QUALS (*node)) + { + *node = build_qualified_type (*node, TYPE_QUALS (orig)); + TYPE_NAME (*node) = orig; + } return NULL_TREE; } diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 7c7e21d..009c8ef 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -747,7 +747,7 @@ enum cxx_dialect { cxx26 }; -/* The C++ dialect being used. C++98 is the default. */ +/* The C++ dialect being used. C++17 is the default. */ extern enum cxx_dialect cxx_dialect; /* Maximum template instantiation depth. This limit is rather diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 4aea902..5476d10 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1090,7 +1090,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__cpp_constexpr_exceptions=202411L"); cpp_define (pfile, "__cpp_static_assert=202306L"); cpp_define (pfile, "__cpp_placeholder_variables=202306L"); - cpp_define (pfile, "__cpp_structured_bindings=202403L"); + cpp_define (pfile, "__cpp_structured_bindings=202411L"); cpp_define (pfile, "__cpp_deleted_function=202403L"); cpp_define (pfile, "__cpp_variadic_friend=202403L"); cpp_define (pfile, "__cpp_pack_indexing=202311L"); diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index c652e82..3fb12b9 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -959,6 +959,15 @@ c_common_post_options (const char **pfilename) if (warn_enum_compare == -1) warn_enum_compare = c_dialect_cxx () ? 1 : 0; + /* For C++26 default to -Wkeyword-macro if -Wpedantic. */ + if (cxx_dialect >= cxx26 && pedantic) + { + SET_OPTION_IF_UNSET (&global_options, &global_options_set, + warn_keyword_macro, 1); + if (warn_keyword_macro) + cpp_opts->cpp_warn_keyword_macro = warn_keyword_macro; + } + /* -Wpacked-bitfield-compat is on by default for the C languages. The warning is issued in stor-layout.cc which is not part of the front-end so we need to selectively turn it on here. */ diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 12877eb..0ee2c30 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -964,6 +964,10 @@ Enum(warn_leading_whitespace_kind) String(tabs) Value(2) EnumValue Enum(warn_leading_whitespace_kind) String(blanks) Value(3) +Wkeyword-macro +C ObjC C++ ObjC++ CPP(cpp_warn_keyword_macro) CppReason(CPP_W_KEYWORD_MACRO) Var(warn_keyword_macro) Init(0) Warning +Warn about defining or undefining macros with identifiers equal to keywords (or for C++ conditional keywords or standard attribute names). + Wleading-whitespace= C ObjC C++ ObjC++ CPP(cpp_warn_leading_whitespace) CppReason(CPP_W_LEADING_WHITESPACE) Enum(warn_leading_whitespace_kind) Joined RejectNegative Var(warn_leading_whitespace) Init(0) Warning Warn about leading whitespace style issues on lines except when in raw string literals. diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls index 5c97593..6eb1178 100644 --- a/gcc/c-family/c.opt.urls +++ b/gcc/c-family/c.opt.urls @@ -508,6 +508,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Winvalid-utf8) Wjump-misses-init UrlSuffix(gcc/Warning-Options.html#index-Wjump-misses-init) +Wkeyword-macro +UrlSuffix(gcc/Warning-Options.html#index-Wkeyword-macro) + Wleading-whitespace= UrlSuffix(gcc/Warning-Options.html#index-Wleading-whitespace_003d) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 464e5a1..2e5c896 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,45 @@ +2025-08-06 Alexandre Oliva <oliva@adacore.com> + + * c-tree.h (C_BOOLEAN_TYPE_P): Cover hardbools as well. + * c-typeck.cc (convert_lvalue_to_rvalue): New overload and + wrapper. + (build_atomic_assign, build_modify_expr): Use it. + (build_asm_expr, handle_omp-array_sections_1): Simplify with + it. + (build_unary_op): Handle hardbools. + +2025-08-06 Martin Uecker <uecker@tugraz.at> + + PR c/108931 + * c-typeck.cc (composite_type_cond): Renamed from + composite_type with argument for condition + (composite_type): New function. + (composite_type_internal): Implement new logic. + (build_conditional_expr): Pass condition. + (common_pointer_type): Adapt. + (pointer_diff): Adapt. + (build_binary_op): Adapt. + +2025-08-06 Martin Uecker <uecker@tugraz.at> + + PR c/121217 + * c-typeck.cc (tagged_types_tu_compatible_p): Add check. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * c-parser.cc (c_parser_omp_clause_from_to): Parse 'iterator' modifier. + * c-typeck.cc (c_finish_omp_clauses): Finish iterators for to/from + clauses. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + Andrew Stubbs <ams@baylibre.com> + + * c-parser.cc (c_parser_omp_variable_list): Use location of the + map expression as the clause location. + (c_parser_omp_clause_map): Parse 'iterator' modifier. + * c-typeck.cc (c_finish_omp_clauses): Finish iterators. Apply + iterators to generated clauses. + 2025-08-02 Martin Uecker <uecker@tugraz.at> * c-decl.cc (get_parm_array_spec): Remove. diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 7850365..8e8bac6 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -4825,6 +4825,29 @@ c_init_decl_processing (void) make_fname_decl = c_make_fname_decl; start_fname_decls (); + + if (warn_keyword_macro) + { + for (unsigned int i = 0; i < num_c_common_reswords; ++i) + /* For C register keywords which don't start with underscore + or start with just single underscore. Don't complain about + ObjC or Transactional Memory keywords. */ + if (c_common_reswords[i].word[0] == '_' + && c_common_reswords[i].word[1] == '_') + continue; + else if (c_common_reswords[i].disable + & (D_TRANSMEM | D_OBJC | D_CXX_OBJC)) + continue; + else + { + tree id = get_identifier (c_common_reswords[i].word); + if (C_IS_RESERVED_WORD (id) + && C_RID_CODE (id) != RID_CXX_COMPAT_WARN) + cpp_lookup (parse_in, + (const unsigned char *) IDENTIFIER_POINTER (id), + IDENTIFIER_LENGTH (id))->flags |= NODE_WARN; + } + } } /* Create the VAR_DECL at LOC for __FUNCTION__ etc. ID is the name to diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index bb0b113..dba94ab 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -163,7 +163,8 @@ along with GCC; see the file COPYING3. If not see (TREE_CODE (TYPE) == BOOLEAN_TYPE \ || (TREE_CODE (TYPE) == ENUMERAL_TYPE \ && ENUM_UNDERLYING_TYPE (TYPE) != NULL_TREE \ - && TREE_CODE (ENUM_UNDERLYING_TYPE (TYPE)) == BOOLEAN_TYPE)) + && (TREE_CODE (ENUM_UNDERLYING_TYPE (TYPE)) == BOOLEAN_TYPE \ + || c_hardbool_type_attr (TYPE)))) /* Record parser information about an expression that is irrelevant for code generation alongside a tree representing its value. */ diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index e0d0a44..7a95f72 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -641,7 +641,8 @@ struct composite_cache { }; tree -composite_type_internal (tree t1, tree t2, struct composite_cache* cache) +composite_type_internal (tree t1, tree t2, tree cond, + struct composite_cache* cache) { enum tree_code code1; enum tree_code code2; @@ -686,8 +687,8 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) { tree pointed_to_1 = TREE_TYPE (t1); tree pointed_to_2 = TREE_TYPE (t2); - tree target = composite_type_internal (pointed_to_1, - pointed_to_2, cache); + tree target = composite_type_internal (pointed_to_1, pointed_to_2, + cond, cache); t1 = c_build_pointer_type_for_mode (target, TYPE_MODE (t1), false); t1 = c_build_type_attribute_variant (t1, attributes); return qualify_type (t1, t2); @@ -695,25 +696,20 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) case ARRAY_TYPE: { - tree elt = composite_type_internal (TREE_TYPE (t1), TREE_TYPE (t2), - cache); - int quals; - tree unqual_elt; tree d1 = TYPE_DOMAIN (t1); tree d2 = TYPE_DOMAIN (t2); - bool d1_variable, d2_variable; - bool d1_zero, d2_zero; - bool t1_complete, t2_complete; /* We should not have any type quals on arrays at all. */ gcc_assert (!TYPE_QUALS_NO_ADDR_SPACE (t1) && !TYPE_QUALS_NO_ADDR_SPACE (t2)); - t1_complete = COMPLETE_TYPE_P (t1); - t2_complete = COMPLETE_TYPE_P (t2); + bool t1_complete = COMPLETE_TYPE_P (t1); + bool t2_complete = COMPLETE_TYPE_P (t2); - d1_zero = d1 == NULL_TREE || !TYPE_MAX_VALUE (d1); - d2_zero = d2 == NULL_TREE || !TYPE_MAX_VALUE (d2); + bool d1_zero = d1 == NULL_TREE || !TYPE_MAX_VALUE (d1); + bool d2_zero = d2 == NULL_TREE || !TYPE_MAX_VALUE (d2); + + bool d1_variable, d2_variable; d1_variable = (!d1_zero && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST @@ -722,10 +718,8 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)); - bool use1 = TYPE_DOMAIN (t1) - && (d2_variable || d2_zero || !d1_variable); - bool use2 = TYPE_DOMAIN (t2) - && (d1_variable || d1_zero || !d2_variable); + bool use1 = d1 && (d2_variable || d2_zero || !d1_variable); + bool use2 = d2 && (d1_variable || d1_zero || !d2_variable); /* If the first is an unspecified size pick the other one. */ if (d2_variable && c_type_unspecified_p (t1)) @@ -734,25 +728,53 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) use1 = false; } - /* Save space: see if the result is identical to one of the args. */ - if (elt == TREE_TYPE (t1) && use1) - return c_build_type_attribute_variant (t1, attributes); - if (elt == TREE_TYPE (t2) && use2) - return c_build_type_attribute_variant (t2, attributes); + /* If both are VLAs but not unspecified and we are in the + conditional operator, we create a conditional to select + the size of the active branch. */ + bool use0 = cond && d1_variable && !c_type_unspecified_p (t1) + && d2_variable && !c_type_unspecified_p (t2); + + tree td; + tree elt = composite_type_internal (TREE_TYPE (t1), TREE_TYPE (t2), + cond, cache); + + if (!use0) + { + /* Save space: see if the result is identical to one of the args. */ + if (elt == TREE_TYPE (t1) && use1) + return c_build_type_attribute_variant (t1, attributes); + if (elt == TREE_TYPE (t2) && use2) + return c_build_type_attribute_variant (t2, attributes); + + if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1)) + return c_build_type_attribute_variant (t1, attributes); + if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1)) + return c_build_type_attribute_variant (t2, attributes); + + td = TYPE_DOMAIN (use1 ? t1 : t2); + } + else + { + /* Not used in C. */ + gcc_assert (size_zero_node == TYPE_MIN_VALUE (d1)); + gcc_assert (size_zero_node == TYPE_MIN_VALUE (d2)); + + tree d = fold_build3_loc (UNKNOWN_LOCATION, COND_EXPR, sizetype, + cond, TYPE_MAX_VALUE (d1), + TYPE_MAX_VALUE (d2)); - if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1)) - return c_build_type_attribute_variant (t1, attributes); - if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1)) - return c_build_type_attribute_variant (t2, attributes); + td = build_index_type (d); + } /* Merge the element types, and have a size if either arg has one. We may have qualifiers on the element types. To set up TYPE_MAIN_VARIANT correctly, we need to form the composite of the unqualified types and add the qualifiers back at the end. */ - quals = TYPE_QUALS (strip_array_types (elt)); - unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED); - t1 = c_build_array_type (unqual_elt, TYPE_DOMAIN (use1 ? t1 : t2)); + int quals = TYPE_QUALS (strip_array_types (elt)); + tree unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED); + + t1 = c_build_array_type (unqual_elt, td); /* Check that a type which has a varying outermost dimension got marked has having a variable size. */ @@ -819,7 +841,7 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) gcc_assert (DECL_NAME (a) == DECL_NAME (b)); gcc_checking_assert (!DECL_NAME (a) || comptypes (ta, tb)); - tree t = composite_type_internal (ta, tb, cache); + tree t = composite_type_internal (ta, tb, cond, cache); tree f = build_decl (input_location, FIELD_DECL, DECL_NAME (a), t); DECL_PACKED (f) = DECL_PACKED (a); @@ -876,8 +898,8 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) /* Function types: prefer the one that specified arg types. If both do, merge the arg types. Also merge the return types. */ { - tree valtype = composite_type_internal (TREE_TYPE (t1), - TREE_TYPE (t2), cache); + tree valtype = composite_type_internal (TREE_TYPE (t1), TREE_TYPE (t2), + cond, cache); tree p1 = TYPE_ARG_TYPES (t1); tree p2 = TYPE_ARG_TYPES (t2); int len; @@ -956,7 +978,7 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) { TREE_VALUE (n) = composite_type_internal (TREE_TYPE (memb), TREE_VALUE (p2), - cache); + cond, cache); pedwarn (input_location, OPT_Wpedantic, "function types not truly compatible in ISO C"); goto parm_done; @@ -979,14 +1001,14 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) TREE_VALUE (n) = composite_type_internal (TREE_TYPE (memb), TREE_VALUE (p1), - cache); + cond, cache); pedwarn (input_location, OPT_Wpedantic, "function types not truly compatible in ISO C"); goto parm_done; } } } - TREE_VALUE (n) = composite_type_internal (mv1, mv2, cache); + TREE_VALUE (n) = composite_type_internal (mv1, mv2, cond, cache); parm_done: ; } @@ -1001,18 +1023,25 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) } tree -composite_type (tree t1, tree t2) +composite_type_cond (tree t1, tree t2, tree cond) { gcc_checking_assert (comptypes_check_for_composite (t1, t2)); struct composite_cache cache = { }; - tree n = composite_type_internal (t1, t2, &cache); + tree n = composite_type_internal (t1, t2, cond, &cache); gcc_checking_assert (comptypes_check_for_composite (n, t1)); gcc_checking_assert (comptypes_check_for_composite (n, t2)); return n; } + +tree +composite_type (tree t1, tree t2) +{ + return composite_type_cond (t1, t2, NULL_TREE); +} + /* Return the type of a conditional expression between pointers to possibly differently qualified versions of compatible types. @@ -1020,7 +1049,7 @@ composite_type (tree t1, tree t2) true; if that isn't so, this may crash. */ static tree -common_pointer_type (tree t1, tree t2) +common_pointer_type (tree t1, tree t2, tree cond) { tree attributes; unsigned target_quals; @@ -1047,8 +1076,8 @@ common_pointer_type (tree t1, tree t2) qualifiers of the two types' targets. */ tree pointed_to_1 = TREE_TYPE (t1); tree pointed_to_2 = TREE_TYPE (t2); - tree target = composite_type (TYPE_MAIN_VARIANT (pointed_to_1), - TYPE_MAIN_VARIANT (pointed_to_2)); + tree target = composite_type_cond (TYPE_MAIN_VARIANT (pointed_to_1), + TYPE_MAIN_VARIANT (pointed_to_2), cond); /* Strip array types to get correct qualifier for pointers to arrays */ quals1 = TYPE_QUALS_NO_ADDR_SPACE (strip_array_types (pointed_to_1)); @@ -2651,6 +2680,20 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp, return exp; } +/* Wrapper for the overload above, same arguments but for tree rather than + c_expr. This is important for hardbools to decay to bools. */ + +static inline tree +convert_lvalue_to_rvalue (location_t loc, tree val, + bool convert_p, bool read_p, bool for_init = false) +{ + struct c_expr expr; + memset (&expr, 0, sizeof (expr)); + expr.value = val; + expr = convert_lvalue_to_rvalue (loc, expr, convert_p, read_p, for_init); + return expr.value; +} + /* EXP is an expression of integer type. Apply the integer promotions to it and return the promoted value. */ @@ -4929,7 +4972,7 @@ pointer_diff (location_t loc, tree op0, tree op1, tree *instrument_expr) if (!addr_space_superset (as0, as1, &as_common)) gcc_unreachable (); - common_type = common_pointer_type (TREE_TYPE (op0), TREE_TYPE (op1)); + common_type = common_pointer_type (TREE_TYPE (op0), TREE_TYPE (op1), NULL_TREE); op0 = convert (common_type, op0); op1 = convert (common_type, op1); } @@ -5274,7 +5317,9 @@ cas_loop: /* newval = old + val; */ if (rhs_type != rhs_semantic_type) val = build1 (EXCESS_PRECISION_EXPR, nonatomic_rhs_semantic_type, val); - rhs = build_binary_op (loc, modifycode, old, val, true); + rhs = build_binary_op (loc, modifycode, + convert_lvalue_to_rvalue (loc, old, true, true), + val, true); if (TREE_CODE (rhs) == EXCESS_PRECISION_EXPR) { tree eptype = TREE_TYPE (rhs); @@ -5730,7 +5775,48 @@ build_unary_op (location_t location, enum tree_code code, tree xarg, goto return_build_unary_op; } - if (C_BOOLEAN_TYPE_P (TREE_TYPE (arg))) + tree true_res; + if (c_hardbool_type_attr (TREE_TYPE (arg), NULL, &true_res)) + { + tree larg = stabilize_reference (arg); + tree sarg = save_expr (larg); + switch (code) + { + case PREINCREMENT_EXPR: + val = build2 (MODIFY_EXPR, TREE_TYPE (larg), larg, true_res); + val = build2 (COMPOUND_EXPR, TREE_TYPE (larg), sarg, val); + break; + case POSTINCREMENT_EXPR: + val = build2 (MODIFY_EXPR, TREE_TYPE (larg), larg, true_res); + val = build2 (COMPOUND_EXPR, TREE_TYPE (larg), val, sarg); + val = build2 (COMPOUND_EXPR, TREE_TYPE (larg), sarg, val); + break; + case PREDECREMENT_EXPR: + { + tree rarg = convert_lvalue_to_rvalue (location, sarg, + true, true); + rarg = invert_truthvalue_loc (location, rarg); + rarg = convert (TREE_TYPE (sarg), rarg); + val = build2 (MODIFY_EXPR, TREE_TYPE (larg), larg, rarg); + } + break; + case POSTDECREMENT_EXPR: + { + tree rarg = convert_lvalue_to_rvalue (location, sarg, + true, true); + rarg = invert_truthvalue_loc (location, rarg); + tree iarg = convert (TREE_TYPE (larg), rarg); + val = build2 (MODIFY_EXPR, TREE_TYPE (larg), larg, iarg); + val = build2 (COMPOUND_EXPR, TREE_TYPE (larg), val, sarg); + val = build2 (COMPOUND_EXPR, TREE_TYPE (larg), sarg, val); + } + break; + default: + gcc_unreachable (); + } + TREE_SIDE_EFFECTS (val) = 1; + } + else if (C_BOOLEAN_TYPE_P (TREE_TYPE (arg))) val = boolean_increment (code, arg); else val = build2 (code, TREE_TYPE (arg), arg, inc); @@ -6383,7 +6469,10 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp, addr_space_t as_common; if (comp_target_types (colon_loc, type1, type2)) - result_type = common_pointer_type (type1, type2); + { + ifexp = save_expr (ifexp); + result_type = common_pointer_type (type1, type2, ifexp); + } else if (null_pointer_constant_p (orig_op1)) result_type = type2; else if (null_pointer_constant_p (orig_op2)) @@ -7340,8 +7429,10 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype, clear_decl_read = true; } - newrhs = build_binary_op (location, - modifycode, lhs, newrhs, true); + newrhs = build_binary_op (location, modifycode, + convert_lvalue_to_rvalue (location, lhs, + true, true), + newrhs, true); if (clear_decl_read) DECL_READ_P (lhs) = 0; @@ -12733,11 +12824,9 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, } else { - struct c_expr expr; - memset (&expr, 0, sizeof (expr)); - expr.value = input; - expr = convert_lvalue_to_rvalue (loc, expr, true, false); - input = c_fully_fold (expr.value, false, NULL); + input = c_fully_fold (convert_lvalue_to_rvalue (loc, input, + true, false), + false, NULL); if (input != error_mark_node && VOID_TYPE_P (TREE_TYPE (input))) { @@ -14393,7 +14482,7 @@ build_binary_op (location_t location, enum tree_code code, Otherwise, the targets must be compatible and both must be object or both incomplete. */ if (comp_target_types (location, type0, type1)) - result_type = common_pointer_type (type0, type1); + result_type = common_pointer_type (type0, type1, NULL_TREE); else if (!addr_space_superset (as0, as1, &as_common)) { error_at (location, "comparison of pointers to " @@ -14532,7 +14621,7 @@ build_binary_op (location_t location, enum tree_code code, if (comp_target_types (location, type0, type1)) { - result_type = common_pointer_type (type0, type1); + result_type = common_pointer_type (type0, type1, NULL_TREE); if (!COMPLETE_TYPE_P (TREE_TYPE (type0)) != !COMPLETE_TYPE_P (TREE_TYPE (type1))) pedwarn_c99 (location, OPT_Wpedantic, @@ -15359,12 +15448,8 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, /* If the array section is pointer based and the pointer itself is _Atomic qualified, we need to atomically load the pointer. */ - c_expr expr; - memset (&expr, 0, sizeof (expr)); - expr.value = ret; - expr = convert_lvalue_to_rvalue (OMP_CLAUSE_LOCATION (c), - expr, false, false); - ret = expr.value; + ret = convert_lvalue_to_rvalue (OMP_CLAUSE_LOCATION (c), + ret, false, false); } return ret; } diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index d30c9c7..2dbaf4a 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -25435,20 +25435,41 @@ aarch64_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED, int global) return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type; } +/* Return true if function declaration FNDECL needs to be marked as + having a variant PCS. */ + +static bool +aarch64_is_variant_pcs (tree fndecl) +{ + /* Check for ABIs that preserve more registers than usual. */ + arm_pcs pcs = (arm_pcs) fndecl_abi (fndecl).id (); + if (pcs == ARM_PCS_SIMD || pcs == ARM_PCS_SVE) + return true; + + /* Check for ABIs that allow PSTATE.SM to be 1 on entry. */ + tree fntype = TREE_TYPE (fndecl); + if (aarch64_fntype_pstate_sm (fntype) != AARCH64_ISA_MODE_SM_OFF) + return true; + + /* Check for ABIs that require PSTATE.ZA to be 1 on entry, either because + of ZA or ZT0. */ + if (aarch64_fntype_pstate_za (fntype) != 0) + return true; + + return false; +} + /* Output .variant_pcs for aarch64_vector_pcs function symbols. */ static void aarch64_asm_output_variant_pcs (FILE *stream, const tree decl, const char* name) { - if (TREE_CODE (decl) == FUNCTION_DECL) + if (TREE_CODE (decl) == FUNCTION_DECL + && aarch64_is_variant_pcs (decl)) { - arm_pcs pcs = (arm_pcs) fndecl_abi (decl).id (); - if (pcs == ARM_PCS_SIMD || pcs == ARM_PCS_SVE) - { - fprintf (stream, "\t.variant_pcs\t"); - assemble_name (stream, name); - fprintf (stream, "\n"); - } + fprintf (stream, "\t.variant_pcs\t"); + assemble_name (stream, name); + fprintf (stream, "\n"); } } diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 791f3b9..49af963 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2477,9 +2477,9 @@ constexpr wide_int_bitmask PTA_DIAMONDRAPIDS = PTA_GRANITERAPIDS_D | PTA_MOVRS | PTA_AMX_MOVRS | PTA_USER_MSR; constexpr wide_int_bitmask PTA_BDVER1 = PTA_64BIT | PTA_MMX | PTA_SSE - | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 - | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_FMA4 - | PTA_XOP | PTA_LWP | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE; + | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_POPCNT | PTA_LZCNT + | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL + | PTA_AVX | PTA_FMA4 | PTA_XOP | PTA_LWP | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE; constexpr wide_int_bitmask PTA_BDVER2 = PTA_BDVER1 | PTA_BMI | PTA_TBM | PTA_F16C | PTA_FMA; constexpr wide_int_bitmask PTA_BDVER3 = PTA_BDVER2 | PTA_XSAVEOPT @@ -2487,13 +2487,13 @@ constexpr wide_int_bitmask PTA_BDVER3 = PTA_BDVER2 | PTA_XSAVEOPT constexpr wide_int_bitmask PTA_BDVER4 = PTA_BDVER3 | PTA_AVX2 | PTA_BMI2 | PTA_RDRND | PTA_MOVBE | PTA_MWAITX; -constexpr wide_int_bitmask PTA_ZNVER1 = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 - | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 - | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_AVX2 | PTA_BMI | PTA_BMI2 - | PTA_F16C | PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT - | PTA_FSGSBASE | PTA_RDRND | PTA_MOVBE | PTA_MWAITX | PTA_ADX | PTA_RDSEED - | PTA_CLZERO | PTA_CLFLUSHOPT | PTA_XSAVEC | PTA_XSAVES | PTA_SHA | PTA_LZCNT - | PTA_POPCNT; +constexpr wide_int_bitmask PTA_ZNVER1 = PTA_64BIT | PTA_MMX | PTA_SSE + | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_POPCNT | PTA_LZCNT + | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL + | PTA_AVX | PTA_AVX2 | PTA_BMI | PTA_BMI2 | PTA_F16C | PTA_FMA | PTA_PRFCHW + | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE | PTA_RDRND | PTA_MOVBE + | PTA_MWAITX | PTA_ADX | PTA_RDSEED | PTA_CLZERO | PTA_CLFLUSHOPT + | PTA_XSAVEC | PTA_XSAVES | PTA_SHA; constexpr wide_int_bitmask PTA_ZNVER2 = PTA_ZNVER1 | PTA_CLWB | PTA_RDPID | PTA_WBNOINVD; constexpr wide_int_bitmask PTA_ZNVER3 = PTA_ZNVER2 | PTA_VAES | PTA_VPCLMULQDQ @@ -2506,19 +2506,19 @@ constexpr wide_int_bitmask PTA_ZNVER5 = PTA_ZNVER4 | PTA_AVXVNNI | PTA_MOVDIRI | PTA_MOVDIR64B | PTA_AVX512VP2INTERSECT | PTA_PREFETCHI; constexpr wide_int_bitmask PTA_BTVER1 = PTA_64BIT | PTA_MMX | PTA_SSE - | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4A | PTA_ABM | PTA_CX16 - | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE; + | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4A | PTA_LZCNT | PTA_POPCNT + | PTA_ABM | PTA_CX16 | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE; constexpr wide_int_bitmask PTA_BTVER2 = PTA_BTVER1 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_BMI | PTA_F16C | PTA_MOVBE | PTA_XSAVEOPT; constexpr wide_int_bitmask PTA_LUJIAZUI = PTA_64BIT | PTA_MMX | PTA_SSE - | PTA_SSE2 | PTA_SSE3 | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 - | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_BMI | PTA_BMI2 | PTA_PRFCHW - | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE | PTA_RDRND | PTA_MOVBE - | PTA_ADX | PTA_RDSEED | PTA_POPCNT; + | PTA_SSE2 | PTA_SSE3 | PTA_CX16 | PTA_LZCNT | PTA_POPCNT | PTA_ABM + | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_BMI + | PTA_BMI2 | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE + | PTA_RDRND | PTA_MOVBE | PTA_ADX | PTA_RDSEED; constexpr wide_int_bitmask PTA_YONGFENG = PTA_LUJIAZUI | PTA_AVX | PTA_AVX2 - | PTA_F16C | PTA_FMA | PTA_SHA | PTA_LZCNT; + | PTA_F16C | PTA_FMA | PTA_SHA; #ifndef GENERATOR_FILE diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2b0dd66..6686f10 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -18298,17 +18298,17 @@ (any_rotate:SWI (match_operand:SWI 1 "const_int_operand") (subreg:QI - (and - (match_operand 2 "int248_register_operand") - (match_operand 3 "const_int_operand")) 0)))] + (match_operator 4 "and_operator" + [(match_operand 2 "int248_register_operand") + (match_operand 3 "const_int_operand")]) 0)))] "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1)) == GET_MODE_BITSIZE (<MODE>mode) - 1" - [(set (match_dup 4) (match_dup 1)) + [(set (match_dup 5) (match_dup 1)) (set (match_dup 0) - (any_rotate:SWI (match_dup 4) + (any_rotate:SWI (match_dup 5) (subreg:QI - (and:SI (match_dup 2) (match_dup 3)) 0)))] - "operands[4] = gen_reg_rtx (<MODE>mode);") + (match_op_dup 4 [(match_dup 2) (match_dup 3)]) 0)))] + "operands[5] = gen_reg_rtx (<MODE>mode);") (define_insn_and_split "*<insn><mode>3_mask_1" [(set (match_operand:SWI 0 "nonimmediate_operand") diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 0f31090..175798c 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1714,10 +1714,14 @@ (define_predicate "div_operator" (match_code "div")) -;; Return true if this is a and, ior or xor operation. +;; Return true if this is an and, ior or xor operation. (define_predicate "logic_operator" (match_code "and,ior,xor")) +;; Return true if this is an and operation. +(define_predicate "and_operator" + (match_code "and")) + ;; Return true if this is a plus, minus, and, ior or xor operation. (define_predicate "plusminuslogic_operator" (match_code "plus,minus,and,ior,xor")) diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index 012b6db..d044f9a 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -9239,15 +9239,12 @@ print_operand (FILE *file, rtx x, int code) else if (code == 'h') fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((CONST_WIDE_INT_ELT (x, 0) & 0xffff) ^ 0x8000) - 0x8000); + /* Support arbitrary _BitInt constants in asm statements. */ + else if (code == 0) + output_addr_const (file, x); else - { - if (code == 0) - output_operand_lossage ("invalid constant - try using " - "an output modifier"); - else - output_operand_lossage ("invalid constant for output modifier '%c'", - code); - } + output_operand_lossage ("invalid constant for output modifier '%c'", + code); break; case CONST_VECTOR: switch (code) @@ -18768,6 +18765,27 @@ s390_c_mode_for_floating_type (enum tree_index ti) return default_mode_for_floating_type (ti); } +/* Return true if _BitInt(N) is supported and fill its details into *INFO. */ + +bool +s390_bitint_type_info (int n, struct bitint_info *info) +{ + if (!TARGET_64BIT) + return false; + if (n <= 8) + info->limb_mode = QImode; + else if (n <= 16) + info->limb_mode = HImode; + else if (n <= 32) + info->limb_mode = SImode; + else + info->limb_mode = DImode; + info->abi_limb_mode = info->limb_mode; + info->big_endian = true; + info->extended = true; + return true; +} + /* Initialize GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -19089,6 +19107,9 @@ s390_c_mode_for_floating_type (enum tree_index ti) #undef TARGET_DOCUMENTATION_NAME #define TARGET_DOCUMENTATION_NAME "S/390" +#undef TARGET_C_BITINT_TYPE_INFO +#define TARGET_C_BITINT_TYPE_INFO s390_bitint_type_info + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-s390.h" diff --git a/gcc/configure b/gcc/configure index bacdd29..cab9c75 100755 --- a/gcc/configure +++ b/gcc/configure @@ -872,7 +872,6 @@ c_strict_warn strict_warn c_loose_warn loose_warn -aliasing_flags CPP EGREP GREP @@ -7126,45 +7125,6 @@ $as_echo "#define HAVE_SWAP_IN_UTILITY 1" >>confdefs.h fi -# Check whether compiler is affected by placement new aliasing bug (PR 29286). -# If the host compiler is affected by the bug, and we build with optimization -# enabled (which happens e.g. when cross-compiling), the pool allocator may -# get miscompiled. Use -fno-strict-aliasing to work around this problem. -# Since there is no reliable feature check for the presence of this bug, -# we simply use a GCC version number check. (This should never trigger for -# stages 2 or 3 of a native bootstrap.) -aliasing_flags= -if test "$GCC" = yes; then - saved_CXXFLAGS="$CXXFLAGS" - - # The following test compilation will succeed if and only if $CXX accepts - # -fno-strict-aliasing *and* is older than GCC 4.3. - CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX is affected by placement new aliasing bug" >&5 -$as_echo_n "checking whether $CXX is affected by placement new aliasing bug... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) -#error compiler not affected by placement new aliasing bug -#endif - -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; }; aliasing_flags='-fno-strict-aliasing' -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - CXXFLAGS="$saved_CXXFLAGS" -fi - - - - # --------------------- # Warnings and checking # --------------------- @@ -21522,7 +21482,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 21525 "configure" +#line 21485 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -21628,7 +21588,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 21631 "configure" +#line 21591 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/gcc/configure.ac b/gcc/configure.ac index 2c43b38..ac1f0e9 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -563,35 +563,6 @@ if test $ac_cv_std_swap_in_utility = yes; then [Define if <utility> defines std::swap.]) fi -# Check whether compiler is affected by placement new aliasing bug (PR 29286). -# If the host compiler is affected by the bug, and we build with optimization -# enabled (which happens e.g. when cross-compiling), the pool allocator may -# get miscompiled. Use -fno-strict-aliasing to work around this problem. -# Since there is no reliable feature check for the presence of this bug, -# we simply use a GCC version number check. (This should never trigger for -# stages 2 or 3 of a native bootstrap.) -aliasing_flags= -if test "$GCC" = yes; then - saved_CXXFLAGS="$CXXFLAGS" - - # The following test compilation will succeed if and only if $CXX accepts - # -fno-strict-aliasing *and* is older than GCC 4.3. - CXXFLAGS="$CXXFLAGS -fno-strict-aliasing" - AC_MSG_CHECKING([whether $CXX is affected by placement new aliasing bug]) - AC_COMPILE_IFELSE([AC_LANG_SOURCE([ -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) -#error compiler not affected by placement new aliasing bug -#endif -])], - [AC_MSG_RESULT([yes]); aliasing_flags='-fno-strict-aliasing'], - [AC_MSG_RESULT([no])]) - - CXXFLAGS="$saved_CXXFLAGS" -fi -AC_SUBST(aliasing_flags) - - - # --------------------- # Warnings and checking # --------------------- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cb4ff09..8e9b8ea 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,28 @@ +2025-08-06 Patrick Palka <ppalka@redhat.com> + + PR c++/121231 + PR c++/119688 + PR c++/94511 + * mangle.cc (write_expression): Write out implicit non-trailing + zeroes of a CONSTRUCTOR when the ABI version is at least 21. + +2025-08-06 Jason Merrill <jason@redhat.com> + + * constexpr.cc (cxx_eval_indirect_ref): Improve diagnostic. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * parser.cc (cp_parser_omp_clause_from_to): Parse 'iterator' modifier. + * semantics.cc (finish_omp_clauses): Finish iterators for to/from + clauses. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + Andrew Stubbs <ams@baylibre.com> + + * parser.cc (cp_parser_omp_clause_map): Parse 'iterator' modifier. + * semantics.cc (finish_omp_clauses): Finish iterators. Apply + iterators to generated clauses. + 2025-08-05 Jason Merrill <jason@redhat.com> PR c++/121068 diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index b8ac454..eabf7f8 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -11615,12 +11615,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, } return false; } + tree ve = DECL_VALUE_EXPR (t); /* Treat __PRETTY_FUNCTION__ inside a template function as potentially-constant. */ - else if (DECL_PRETTY_FUNCTION_P (t) - && DECL_VALUE_EXPR (t) == error_mark_node) + if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node) return true; - return RECUR (DECL_VALUE_EXPR (t), rval); + if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC) + return RECUR (TREE_VEC_ELT (ve, 0), rval); + return RECUR (ve, rval); } if (want_rval && (now || !var_in_maybe_constexpr_fn (t)) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 8122fca..ab5b0c9 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -9748,7 +9748,7 @@ get_tuple_size (tree type) /* Return std::tuple_element<I,TYPE>::type. */ static tree -get_tuple_element_type (tree type, unsigned i) +get_tuple_element_type (tree type, unsigned HOST_WIDE_INT i) { tree args = make_tree_vec (2); TREE_VEC_ELT (args, 0) = build_int_cst (integer_type_node, i); @@ -9764,7 +9764,7 @@ get_tuple_element_type (tree type, unsigned i) /* Return e.get<i>() or get<i>(e). */ static tree -get_tuple_decomp_init (tree decl, unsigned i) +get_tuple_decomp_init (tree decl, unsigned HOST_WIDE_INT i) { tree targs = make_tree_vec (1); TREE_VEC_ELT (targs, 0) = build_int_cst (integer_type_node, i); @@ -9870,6 +9870,19 @@ cp_maybe_mangle_decomp (tree decl, cp_decomp *decomp) } } +/* Append #i to DECL_NAME (decl). */ + +static void +set_sb_pack_name (tree decl, unsigned HOST_WIDE_INT i) +{ + tree name = DECL_NAME (decl); + size_t len = IDENTIFIER_LENGTH (name) + 22; + char *n = XALLOCAVEC (char, len); + snprintf (n, len, "%s#" HOST_WIDE_INT_PRINT_UNSIGNED, + IDENTIFIER_POINTER (name), i); + DECL_NAME (decl) = get_identifier (n); +} + /* Finish a decomposition declaration. DECL is the underlying declaration "e", FIRST is the head of a chain of decls for the individual identifiers chained through DECL_CHAIN in reverse order and COUNT is the number of @@ -9926,10 +9939,13 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) auto_vec<tree, 16> v; v.safe_grow (count, true); tree d = first; + int pack = -1; for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d)) { v[count - i - 1] = d; fit_decomposition_lang_decl (d, decl); + if (DECL_PACK_P (d)) + pack = count - i - 1; } tree type = TREE_TYPE (decl); @@ -9951,6 +9967,14 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) tree eltype = NULL_TREE; unsigned HOST_WIDE_INT eltscnt = 0; + /* Structured binding packs when initializer is non-dependent should + have their DECL_VALUE_EXPR set to a TREE_VEC. First two elements + of that TREE_VEC are the base and index, what is normally represented + as DECL_VALUE_EXPR ARRAY_REF <base, index> where index is the index + of the pack first element. The remaining elements of the TREE_VEC + are VAR_DECLs for the pack elements. */ + tree packv = NULL_TREE; + if (TREE_CODE (type) == ARRAY_TYPE) { tree nelts; @@ -9969,7 +9993,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) goto error_out; } eltscnt = tree_to_uhwi (nelts); - if (count != eltscnt) + if (pack != -1 ? count - 1 > eltscnt : count != eltscnt) { cnt_mismatch: auto_diagnostic_group d; @@ -9990,12 +10014,37 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) eltype = TREE_TYPE (type); for (unsigned int i = 0; i < count; i++) { + if ((unsigned) pack == i) + { + packv = make_tree_vec (eltscnt - count + 3); + for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j) + { + tree t; + TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]); + set_sb_pack_name (t, j); + maybe_push_decl (t); + TREE_TYPE (t) = eltype; + layout_decl (t, 0); + if (!processing_template_decl) + { + tree a = unshare_expr (dexp); + a = build4 (ARRAY_REF, eltype, a, size_int (j + pack), + NULL_TREE, NULL_TREE); + SET_DECL_VALUE_EXPR (t, a); + DECL_HAS_VALUE_EXPR_P (t) = 1; + } + } + continue; + } TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); if (processing_template_decl) continue; tree t = unshare_expr (dexp); - t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE); + unsigned HOST_WIDE_INT j = i; + if (pack != -1 && (unsigned) pack < i) + j = i + eltscnt - count; + t = build4 (ARRAY_REF, eltype, t, size_int (j), NULL_TREE, NULL_TREE); SET_DECL_VALUE_EXPR (v[i], t); DECL_HAS_VALUE_EXPR_P (v[i]) = 1; } @@ -10004,17 +10053,41 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) else if (TREE_CODE (type) == COMPLEX_TYPE) { eltscnt = 2; - if (count != eltscnt) + if (pack != -1 ? count - 1 > eltscnt : count != eltscnt) goto cnt_mismatch; eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type)); for (unsigned int i = 0; i < count; i++) { + if ((unsigned) pack == i) + { + packv = make_tree_vec (eltscnt - count + 3); + for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j) + { + tree t; + TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]); + set_sb_pack_name (t, j); + maybe_push_decl (t); + TREE_TYPE (t) = eltype; + layout_decl (t, 0); + if (!processing_template_decl) + { + tree a = build1 (pack + j ? IMAGPART_EXPR : REALPART_EXPR, eltype, + unshare_expr (dexp)); + SET_DECL_VALUE_EXPR (t, a); + DECL_HAS_VALUE_EXPR_P (t) = 1; + } + } + continue; + } TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); if (processing_template_decl) continue; tree t = unshare_expr (dexp); - t = build1 (i ? IMAGPART_EXPR : REALPART_EXPR, eltype, t); + unsigned HOST_WIDE_INT j = i; + if (pack != -1 && (unsigned) pack < i) + j = i + eltscnt - count; + t = build1 (j ? IMAGPART_EXPR : REALPART_EXPR, eltype, t); SET_DECL_VALUE_EXPR (v[i], t); DECL_HAS_VALUE_EXPR_P (v[i]) = 1; } @@ -10026,19 +10099,47 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) error_at (loc, "cannot decompose variable length vector %qT", type); goto error_out; } - if (count != eltscnt) + if (pack != -1 ? count - 1 > eltscnt : count != eltscnt) goto cnt_mismatch; eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type)); for (unsigned int i = 0; i < count; i++) { + if ((unsigned) pack == i) + { + packv = make_tree_vec (eltscnt - count + 3); + for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j) + { + tree t; + TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]); + set_sb_pack_name (t, j); + maybe_push_decl (t); + TREE_TYPE (t) = eltype; + layout_decl (t, 0); + if (!processing_template_decl) + { + tree a = unshare_expr (dexp); + location_t loc = DECL_SOURCE_LOCATION (t); + tree s = size_int (j + pack); + convert_vector_to_array_for_subscript (loc, &a, s); + a = build4 (ARRAY_REF, eltype, a, s, + NULL_TREE, NULL_TREE); + SET_DECL_VALUE_EXPR (t, a); + DECL_HAS_VALUE_EXPR_P (t) = 1; + } + } + continue; + } TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); if (processing_template_decl) continue; tree t = unshare_expr (dexp); + unsigned HOST_WIDE_INT j = i; + if (pack != -1 && (unsigned) pack < i) + j = i + eltscnt - count; convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]), - &t, size_int (i)); - t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE); + &t, size_int (j)); + t = build4 (ARRAY_REF, eltype, t, size_int (j), NULL_TREE, NULL_TREE); SET_DECL_VALUE_EXPR (v[i], t); DECL_HAS_VALUE_EXPR_P (v[i]) = 1; } @@ -10062,11 +10163,11 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) goto error_out; } eltscnt = tree_to_uhwi (tsize); - if (count != eltscnt) + if (pack != -1 ? count - 1 > eltscnt : count != eltscnt) goto cnt_mismatch; - if (test_p) + if (test_p && eltscnt) return true; - if (!processing_template_decl && DECL_DECOMP_BASE (decl)) + if (!processing_template_decl && DECL_DECOMP_BASE (decl) && eltscnt) { /* For structured bindings used in conditions we need to evaluate the conversion of decl (aka e in the standard) to bool or @@ -10096,16 +10197,70 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) location_t sloc = input_location; location_t dloc = DECL_SOURCE_LOCATION (v[i]); + if ((unsigned) pack == i) + { + packv = make_tree_vec (eltscnt - count + 3); + for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j) + { + tree t; + TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]); + set_sb_pack_name (t, j); + input_location = dloc; + tree init = get_tuple_decomp_init (decl, j + pack); + tree eltype = (init == error_mark_node ? error_mark_node + : get_tuple_element_type (type, j + pack)); + input_location = sloc; + + if (VOID_TYPE_P (eltype)) + { + error ("%<std::tuple_element<%wu, %T>::type%> is " + "%<void%>", j + pack, type); + eltype = error_mark_node; + } + if (init == error_mark_node || eltype == error_mark_node) + { + inform (dloc, "in initialization of structured binding " + "pack %qD", v[pack]); + goto error_out; + } + if (j == 0 + && !processing_template_decl + && TREE_STATIC (decl)) + { + sorry_at (dloc, "mangling of structured binding pack " + "elements not implemented yet"); + goto error_out; + } + maybe_push_decl (t); + /* Save the decltype away before reference collapse. */ + hash_map_safe_put<hm_ggc> (decomp_type_table, t, eltype); + eltype = cp_build_reference_type (eltype, !lvalue_p (init)); + TREE_TYPE (t) = eltype; + layout_decl (t, 0); + DECL_HAS_VALUE_EXPR_P (t) = 0; + if (!processing_template_decl) + { + copy_linkage (t, decl); + cp_finish_decl (t, init, /*constexpr*/false, + /*asm*/NULL_TREE, LOOKUP_NORMAL); + } + } + continue; + } + + unsigned HOST_WIDE_INT j = i; + if (pack != -1 && (unsigned) pack < i) + j = i + eltscnt - count; input_location = dloc; - tree init = get_tuple_decomp_init (decl, i); + tree init = get_tuple_decomp_init (decl, j); tree eltype = (init == error_mark_node ? error_mark_node - : get_tuple_element_type (type, i)); + : get_tuple_element_type (type, j)); input_location = sloc; if (VOID_TYPE_P (eltype)) { - error ("%<std::tuple_element<%u, %T>::type%> is %<void%>", - i, type); + error ("%<std::tuple_element<%wu, %T>::type%> is %<void%>", + j, type); eltype = error_mark_node; } if (init == error_mark_node || eltype == error_mark_node) @@ -10159,6 +10314,12 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) goto error_out; else if (btype == NULL_TREE) { + if (pack == 0 && count == 1) + { + eltscnt = 0; + packv = make_tree_vec (2); + goto done; + } error_at (loc, "cannot decompose class type %qT without non-static " "data members", type); goto error_out; @@ -10170,7 +10331,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) continue; else eltscnt++; - if (count != eltscnt) + if (pack != -1 ? count - 1 > eltscnt : count != eltscnt) goto cnt_mismatch; tree t = dexp; if (type != btype) @@ -10179,6 +10340,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) /*nonnull*/false, tf_warning_or_error); type = btype; } + unsigned HOST_WIDE_INT j = 0; unsigned int i = 0; for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field)) if (TREE_CODE (field) != FIELD_DECL @@ -10191,6 +10353,32 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) NULL_TREE); if (REFERENCE_REF_P (tt)) tt = TREE_OPERAND (tt, 0); + if (pack != -1 && j >= (unsigned) pack) + { + if (j == (unsigned) pack) + { + packv = make_tree_vec (eltscnt - count + 3); + i++; + } + if (j < (unsigned) pack + eltscnt - (count - 1)) + { + tree t; + TREE_VEC_ELT (packv, j + 3 - i) = t = copy_node (v[pack]); + set_sb_pack_name (t, j + 1 - i); + maybe_push_decl (t); + TREE_TYPE (t) = TREE_TYPE (tt); + layout_decl (t, 0); + if (!processing_template_decl) + { + SET_DECL_VALUE_EXPR (t, tt); + DECL_HAS_VALUE_EXPR_P (t) = 1; + } + else + DECL_HAS_VALUE_EXPR_P (t) = 0; + j++; + continue; + } + } TREE_TYPE (v[i]) = TREE_TYPE (tt); layout_decl (v[i], 0); if (!processing_template_decl) @@ -10199,7 +10387,26 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool test_p) DECL_HAS_VALUE_EXPR_P (v[i]) = 1; } i++; + j++; } + if (pack != -1 && j == (unsigned) pack) + { + gcc_checking_assert (eltscnt == count - 1); + packv = make_tree_vec (2); + } + } + done: + if (packv) + { + gcc_checking_assert (pack != -1); + TREE_VEC_ELT (packv, 0) = decl; + TREE_VEC_ELT (packv, 1) = size_int (pack); + SET_DECL_VALUE_EXPR (v[pack], packv); + DECL_HAS_VALUE_EXPR_P (v[pack]) = 1; + DECL_IGNORED_P (v[pack]) = 1; + if (!processing_template_decl) + for (unsigned int i = 0; i < TREE_VEC_LENGTH (packv) - 2U; ++i) + pushdecl (TREE_VEC_ELT (packv, 2 + i)); } if (processing_template_decl) { diff --git a/gcc/cp/lex.cc b/gcc/cp/lex.cc index 08a6348..b7d2ac6 100644 --- a/gcc/cp/lex.cc +++ b/gcc/cp/lex.cc @@ -368,6 +368,66 @@ cxx_init (void) cxx_init_decl_processing (); + if (warn_keyword_macro) + { + for (unsigned int i = 0; i < num_c_common_reswords; ++i) + /* For C++ none of the keywords in [lex.key] starts with underscore, + don't register anything like that. Don't complain about + ObjC or Transactional Memory keywords. */ + if (c_common_reswords[i].word[0] == '_') + continue; + else if (c_common_reswords[i].disable & (D_TRANSMEM | D_OBJC)) + continue; + else + { + tree id = get_identifier (c_common_reswords[i].word); + if (IDENTIFIER_KEYWORD_P (id) + /* Don't register keywords with spaces. */ + && IDENTIFIER_POINTER (id)[IDENTIFIER_LENGTH (id) - 1] != ' ') + cpp_lookup (parse_in, + (const unsigned char *) IDENTIFIER_POINTER (id), + IDENTIFIER_LENGTH (id))->flags |= NODE_WARN; + } + auto warn_on = [] (const char *name) { + cpp_lookup (parse_in, (const unsigned char *) name, + strlen (name))->flags |= NODE_WARN; + }; + if (cxx_dialect >= cxx11) + { + warn_on ("final"); + warn_on ("override"); + warn_on ("noreturn"); + if (cxx_dialect < cxx26) + warn_on ("carries_dependency"); + } + if (cxx_dialect >= cxx14) + warn_on ("deprecated"); + if (cxx_dialect >= cxx17) + { + warn_on ("fallthrough"); + warn_on ("maybe_unused"); + warn_on ("nodiscard"); + } + if (cxx_dialect >= cxx20) + { + warn_on ("likely"); + warn_on ("unlikely"); + warn_on ("no_unique_address"); + } + if (flag_modules) + { + warn_on ("import"); + warn_on ("module"); + } + if (cxx_dialect >= cxx23) + warn_on ("assume"); + if (cxx_dialect >= cxx26) + { + warn_on ("replaceable_if_eligible"); + warn_on ("trivially_relocatable_if_eligible"); + } + } + if (c_common_init () == false) { input_location = saved_loc; diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index a8c54c7..743fd74 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -14672,13 +14672,23 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, tree v = DECL_VALUE_EXPR (range_decl); /* For decomposition declaration get all of the corresponding declarations out of the way. */ - if (TREE_CODE (v) == ARRAY_REF - && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0))) + if ((TREE_CODE (v) == ARRAY_REF + && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0))) + || (TREE_CODE (v) == TREE_VEC + && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0)))) { tree d = range_decl; - range_decl = TREE_OPERAND (v, 0); decomp = &decomp_d; - decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1; + if (TREE_CODE (v) == ARRAY_REF) + { + range_decl = TREE_OPERAND (v, 0); + decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1; + } + else + { + range_decl = TREE_VEC_ELT (v, 0); + decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1; + } decomp->decl = d; bool seen_name_independent_decl = false; for (unsigned int i = 0; i < decomp->count; @@ -16843,7 +16853,7 @@ cp_parser_simple_declaration (cp_parser* parser, } /* Helper of cp_parser_simple_declaration, parse a decomposition declaration. - decl-specifier-seq ref-qualifier [opt] [ identifier-list ] + decl-specifier-seq ref-qualifier [opt] [ sb-identifier-list ] initializer ; */ static tree @@ -16856,21 +16866,45 @@ cp_parser_decomposition_declaration (cp_parser *parser, location_t loc = cp_lexer_peek_token (parser->lexer)->location; cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE); - /* Parse the identifier-list. */ + /* Parse the sb-identifier-list. */ auto_vec<cp_expr, 10> v; bool attr_diagnosed = false; int first_attr = -1; + int pack = -1; unsigned int cnt = 0; if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE)) while (true) { + if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) + { + location_t elloc = cp_lexer_peek_token (parser->lexer)->location; + if (!processing_template_decl) + error_at (elloc, "structured binding pack outside of template"); + else if (pack != -1) + error_at (elloc, + "multiple packs in structured binding declaration"); + else + { + if (keyword == RID_MAX + && cxx_dialect >= cxx17 + && cxx_dialect < cxx26) + pedwarn (elloc, OPT_Wc__26_extensions, + "structured binding packs only available with " + "%<-std=c++2c%> or %<-std=gnu++2c%>"); + pack = cnt; + } + cp_lexer_consume_token (parser->lexer); + } cp_expr e = cp_parser_identifier (parser); if (e.get_value () == error_mark_node) break; tree attr = NULL_TREE; if (cp_next_tokens_can_be_std_attribute_p (parser)) { - if (cxx_dialect >= cxx17 && cxx_dialect < cxx26 && !attr_diagnosed) + if (keyword == RID_MAX + && cxx_dialect >= cxx17 + && cxx_dialect < cxx26 + && !attr_diagnosed) { pedwarn (cp_lexer_peek_token (parser->lexer)->location, OPT_Wc__26_extensions, @@ -16931,7 +16965,7 @@ cp_parser_decomposition_declaration (cp_parser *parser, &pushed_scope); tree orig_decl = decl; - unsigned int i; + unsigned int i, j; cp_expr e; cp_decl_specifier_seq decl_specs; clear_decl_specs (&decl_specs); @@ -16939,6 +16973,7 @@ cp_parser_decomposition_declaration (cp_parser *parser, if (decl_specifiers->storage_class == sc_static) decl_specs.storage_class = sc_static; tree prev = decl; + j = 0; FOR_EACH_VEC_ELT (v, i, e) { if (i == 0) @@ -16969,9 +17004,22 @@ cp_parser_decomposition_declaration (cp_parser *parser, prev = decl2; DECL_DECLARED_CONSTEXPR_P (decl2) = DECL_DECLARED_CONSTEXPR_P (decl); DECL_DECLARED_CONSTINIT_P (decl2) = DECL_DECLARED_CONSTINIT_P (decl); + if (j == (unsigned) pack) + { + tree dtype = cxx_make_type (DECLTYPE_TYPE); + DECLTYPE_TYPE_EXPR (dtype) = decl2; + DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (dtype) = 1; + SET_TYPE_STRUCTURAL_EQUALITY (dtype); + tree type = cxx_make_type (TYPE_PACK_EXPANSION); + PACK_EXPANSION_PATTERN (type) = dtype; + SET_TYPE_STRUCTURAL_EQUALITY (type); + PACK_EXPANSION_PARAMETER_PACKS (type) = decl2; + TREE_TYPE (decl2) = type; + } } if (elt_pushed_scope) pop_scope (elt_pushed_scope); + ++j; } if (v.is_empty ()) @@ -46300,6 +46348,14 @@ cp_convert_omp_range_for (tree &this_pre_body, tree &sl, decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1; decomp->decl = decl; } + else if (TREE_CODE (v) == TREE_VEC + && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0))) + { + d = TREE_VEC_ELT (v, 0); + decomp = &decomp_d; + decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1; + decomp->decl = decl; + } } do_range_for_auto_deduction (d, init, decomp); } @@ -46423,6 +46479,15 @@ cp_convert_omp_range_for (tree &this_pre_body, tree &sl, decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1; decomp->decl = d; } + else if (TREE_CODE (v) == TREE_VEC + && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0))) + { + tree d = orig_decl; + orig_decl = TREE_VEC_ELT (v, 0); + decomp = &decomp_d; + decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1; + decomp->decl = d; + } } tree auto_node = type_uses_auto (TREE_TYPE (orig_decl)); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index acfeb81..b6b13ed 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -13981,9 +13981,30 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, else if (is_capture_proxy (parm_pack)) { arg_pack = retrieve_local_specialization (parm_pack); + if (DECL_DECOMPOSITION_P (arg_pack)) + { + orig_arg = arg_pack; + goto expand_sb_pack; + } if (DECL_PACK_P (arg_pack)) arg_pack = NULL_TREE; } + else if (DECL_DECOMPOSITION_P (parm_pack)) + { + orig_arg = retrieve_local_specialization (parm_pack); + expand_sb_pack: + gcc_assert (DECL_DECOMPOSITION_P (orig_arg)); + if (TREE_TYPE (orig_arg) == error_mark_node) + return error_mark_node; + gcc_assert (DECL_HAS_VALUE_EXPR_P (orig_arg)); + arg_pack = DECL_VALUE_EXPR (orig_arg); + tree vec = make_tree_vec (TREE_VEC_LENGTH (arg_pack) - 2); + if (TREE_VEC_LENGTH (vec)) + memcpy (TREE_VEC_BEGIN (vec), &TREE_VEC_ELT (arg_pack, 2), + TREE_VEC_LENGTH (vec) * sizeof (tree)); + arg_pack = make_node (NONTYPE_ARGUMENT_PACK); + ARGUMENT_PACK_ARGS (arg_pack) = vec; + } else { int idx; @@ -13996,7 +14017,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, arg_pack = NULL_TREE; } - orig_arg = arg_pack; + if (orig_arg == NULL_TREE) + orig_arg = arg_pack; if (arg_pack && TREE_CODE (arg_pack) == ARGUMENT_PACK_SELECT) arg_pack = ARGUMENT_PACK_SELECT_FROM_PACK (arg_pack); @@ -14011,8 +14033,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (arg_pack) { - int my_len = - TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack)); + int my_len + = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack)); /* Don't bother trying to do a partial substitution with incomplete packs; we'll try again after deduction. */ @@ -14176,8 +14198,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, /* Update the corresponding argument. */ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) - TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx) = - TREE_TYPE (pack); + TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx) + = TREE_TYPE (pack); else TREE_VEC_ELT (args, idx) = TREE_TYPE (pack); } @@ -15921,7 +15943,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, tsubst_flags_t tcomplain = complain; if (VAR_P (t)) tcomplain |= tf_tst_ok; - type = tsubst (type, args, tcomplain, in_decl); + if (DECL_DECOMPOSITION_P (t) && DECL_PACK_P (t)) + type = NULL_TREE; + else + type = tsubst (type, args, tcomplain, in_decl); /* Substituting the type might have recursively instantiated this same alias (c++/86171). */ if (use_spec_table && gen_tmpl && DECL_ALIAS_TEMPLATE_P (gen_tmpl) @@ -15938,6 +15963,17 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain, { DECL_INITIALIZED_P (r) = 0; DECL_TEMPLATE_INSTANTIATED (r) = 0; + if (DECL_DECOMPOSITION_P (t) && DECL_PACK_P (t)) + { + tree dtype = cxx_make_type (DECLTYPE_TYPE); + DECLTYPE_TYPE_EXPR (dtype) = r; + DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (dtype) = 1; + SET_TYPE_STRUCTURAL_EQUALITY (dtype); + type = cxx_make_type (TYPE_PACK_EXPANSION); + PACK_EXPANSION_PATTERN (type) = dtype; + SET_TYPE_STRUCTURAL_EQUALITY (type); + PACK_EXPANSION_PARAMETER_PACKS (type) = r; + } if (TREE_CODE (type) == FUNCTION_TYPE) { /* It may seem that this case cannot occur, since: @@ -18555,13 +18591,17 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree &orig_declv, if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl)) { tree v = DECL_VALUE_EXPR (decl); - if (TREE_CODE (v) == ARRAY_REF - && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0))) + if ((TREE_CODE (v) == ARRAY_REF + && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0))) + || (TREE_CODE (v) == TREE_VEC + && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0)))) { + v = (TREE_CODE (v) == ARRAY_REF + ? TREE_OPERAND (v, 0) : TREE_VEC_ELT (v, 0)); cp_decomp decomp_d = { NULL_TREE, 0 }; - tree d = tsubst_decl (TREE_OPERAND (v, 0), args, complain); + tree d = tsubst_decl (v, args, complain); maybe_push_decl (d); - d = tsubst_decomp_names (d, TREE_OPERAND (v, 0), args, complain, + d = tsubst_decomp_names (d, v, args, complain, in_decl, &decomp_d); decomp = true; if (d == error_mark_node) @@ -21220,7 +21260,28 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) ++c_inhibit_evaluation_warnings; /* We only want to compute the number of arguments. */ if (PACK_EXPANSION_P (op)) - expanded = tsubst_pack_expansion (op, args, complain, in_decl); + { + expanded = NULL_TREE; + if (DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (op))) + { + tree d = PACK_EXPANSION_PATTERN (op); + if (DECL_HAS_VALUE_EXPR_P (d)) + { + d = DECL_VALUE_EXPR (d); + if (TREE_CODE (d) == TREE_VEC) + { + tree b = TREE_VEC_ELT (d, 0); + if (!type_dependent_expression_p_push (b)) + { + expanded = void_node; + len = TREE_VEC_LENGTH (d) - 2; + } + } + } + } + if (!expanded) + expanded = tsubst_pack_expansion (op, args, complain, in_decl); + } else expanded = tsubst_template_args (ARGUMENT_PACK_ARGS (op), args, complain, in_decl); @@ -29050,6 +29111,24 @@ value_dependent_expression_p (tree expression) case SIZEOF_EXPR: if (SIZEOF_EXPR_TYPE_P (expression)) return dependent_type_p (TREE_TYPE (TREE_OPERAND (expression, 0))); + if (tree p = TREE_OPERAND (expression, 0)) + if (PACK_EXPANSION_P (p) + && DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (p))) + { + tree d = PACK_EXPANSION_PATTERN (p); + if (DECL_HAS_VALUE_EXPR_P (d)) + { + d = DECL_VALUE_EXPR (d); + /* [temp.dep.constexpr]/4: + Expressions of the following form are value-dependent: + sizeof ... ( identifier ) + unless the identifier is a structured binding pack whose + initializer is not dependent. */ + if (TREE_CODE (d) == TREE_VEC + && !type_dependent_expression_p (TREE_VEC_ELT (d, 0))) + return false; + } + } /* FALLTHRU */ case ALIGNOF_EXPR: case TYPEID_EXPR: @@ -29563,6 +29642,22 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees, tree op = TREE_OPERAND (*tp, 0); if (code == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (*tp)) op = TREE_TYPE (op); + else if (code == SIZEOF_EXPR + && PACK_EXPANSION_P (op) + && DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (op))) + { + tree d = PACK_EXPANSION_PATTERN (op); + if (DECL_HAS_VALUE_EXPR_P (d)) + { + d = DECL_VALUE_EXPR (d); + if (TREE_CODE (d) == TREE_VEC + && !type_dependent_expression_p (TREE_VEC_ELT (d, 0))) + { + *walk_subtrees = 0; + return NULL_TREE; + } + } + } if (TYPE_P (op)) { if (dependent_type_p (op)) diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog index 4fe6418..1217b5d 100644 --- a/gcc/d/ChangeLog +++ b/gcc/d/ChangeLog @@ -1,3 +1,7 @@ +2025-08-06 Sam James <sam@gentoo.org> + + * Make-lang.in (ALL_DFLAGS): Don't use ALIASING_FLAGS. + 2025-07-25 David Malcolm <dmalcolm@redhat.com> * d-diagnostic.cc: Likewise. diff --git a/gcc/d/Make-lang.in b/gcc/d/Make-lang.in index 2d444c9..0ddd524 100644 --- a/gcc/d/Make-lang.in +++ b/gcc/d/Make-lang.in @@ -61,7 +61,7 @@ WARN_DFLAGS = -Wall -Wdeprecated NOEXCEPTION_DFLAGS = $(filter-out -fno-rtti, $(NOEXCEPTION_FLAGS)) ALL_DFLAGS = $(DFLAGS-$@) $(GDCFLAGS) -fversion=IN_GCC $(CHECKING_DFLAGS) \ - $(PICFLAG) $(ALIASING_FLAGS) $(NOEXCEPTION_DFLAGS) $(COVERAGE_FLAGS) \ + $(PICFLAG) $(NOEXCEPTION_DFLAGS) $(COVERAGE_FLAGS) \ $(WARN_DFLAGS) DCOMPILE.base = $(GDC) -c $(ALL_DFLAGS) -o $@ diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 64c1217..7423224 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -393,7 +393,7 @@ Note binutils 2.35 or newer is required for LTO to work correctly with GNU libtool that includes doing a bootstrap with LTO enabled. @item gzip version 1.2.4 (or later) or -@itemx bzip2 version 1.0.2 (or later) +@itemx xz version 5.0 (or later) Necessary to uncompress GCC @command{tar} files when source code is obtained via HTTPS mirror sites. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 00468a7..33ae98c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -388,6 +388,7 @@ Objective-C and Objective-C++ Dialects}. -Winit-self -Winline -Wno-int-conversion -Wint-in-bool-context -Wno-int-to-pointer-cast -Wno-invalid-memory-model -Winvalid-pch -Winvalid-utf8 -Wno-unicode -Wjump-misses-init +-Wkeyword-macro -Wlarger-than=@var{byte-size} -Wleading-whitespace=@var{kind} -Wlogical-not-parentheses -Wlogical-op -Wlong-long -Wno-lto-type-mismatch -Wmain -Wmaybe-uninitialized @@ -10399,6 +10400,14 @@ Do not warn if certain built-in macros are redefined. This suppresses warnings for redefinition of @code{__TIMESTAMP__}, @code{__TIME__}, @code{__DATE__}, @code{__FILE__}, and @code{__BASE_FILE__}. +@opindex Wkeyword-macro +@opindex Wno-keyword-macro +@item -Wkeyword-macro +Warn if a keyword is defined as a macro or undefined. +For C++ identifiers with special meaning or standard attribute identifiers +are diagnosed as well. This warning is enabled by default for C++26 +if @code{-Wpedantic} and emits a pedwarn in that case. + @opindex Wfree-labels @opindex Wno-free-labels @item -Wfree-labels @r{(C and Objective-C only)} diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index c723a07..ee9c048 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -8460,14 +8460,10 @@ simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op, if (GET_CODE (op) == SUBREG || GET_CODE (op) == CONCAT - || GET_MODE (op) == VOIDmode) - return NULL_RTX; - - if (MODE_COMPOSITE_P (outermode) - && (CONST_SCALAR_INT_P (op) - || CONST_DOUBLE_AS_FLOAT_P (op) - || CONST_FIXED_P (op) - || GET_CODE (op) == CONST_VECTOR)) + || CONST_SCALAR_INT_P (op) + || CONST_DOUBLE_AS_FLOAT_P (op) + || CONST_FIXED_P (op) + || GET_CODE (op) == CONST_VECTOR) return NULL_RTX; if (validate_subreg (outermode, innermode, op, byte)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1ac6084..df2c843 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,112 @@ +2025-08-06 Sam James <sam@gentoo.org> + + * g++.dg/cpp26/constexpr-new3.C: Escape '[' and ']'. + +2025-08-06 Alexandre Oliva <oliva@adacore.com> + + * gcc.dg/torture/hardbool-ai.c: New. + * gcc.dg/torture/hardbool-vi.c: New. + * gcc.dg/torture/hardbool.c: Handle NO_BITFIELDS. + (add1, preinc, postinc, sub1, predec, postdec): New. + (main): Exercise them. + +2025-08-06 Martin Uecker <uecker@tugraz.at> + + PR c/108931 + * gcc.dg/vla-tert-1.c: New test. + +2025-08-06 Patrick Palka <ppalka@redhat.com> + + PR c++/121231 + PR c++/119688 + PR c++/94511 + * g++.dg/abi/mangle82.C: New test. + * g++.dg/cpp2a/nontype-class73.C: New test. + +2025-08-06 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp26/constexpr-new3.C: Tweak diagnostic. + +2025-08-06 Richard Biener <rguenther@suse.de> + + * gcc.dg/vect/vect-gather-1.c: Adjust to hide N. + +2025-08-06 Tejas Belagod <tejas.belagod@arm.com> + + * gcc.target/aarch64/sve/acle/general/cops.c: Fix test. + +2025-08-06 Yang Yujie <yangyujie@loongson.cn> + + * gcc.dg/torture/bitint-84.c: New test. + +2025-08-06 Yang Yujie <yangyujie@loongson.cn> + + * gcc.dg/torture/bitint-83.c: New test. + +2025-08-06 Yang Yujie <yangyujie@loongson.cn> + + * gcc.dg/bitintext.h (BEXTC1): Define. Convert the copied + object back to the original type before comparison. + (BEXTC): Use BEXTC1 for both the signed and the unsigned case. + +2025-08-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/121413 + * gcc.dg/torture/bitint-85.c: New test. + +2025-08-06 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/121127 + * gcc.dg/bitint-125.c: New test. + +2025-08-06 Yuao Ma <c8ef@outlook.com> + + * gfortran.dg/c_f_pointer_shape_tests_2.f03: Use the new driver. + * gfortran.dg/c_f_pointer_shape_tests_4.f03: Ditto. + * gfortran.dg/c_f_pointer_shape_tests_4_driver.c: Removed. + * gfortran.dg/c_f_pointer_shape_tests_2_driver.c: Renamed to ... + * gfortran.dg/c_f_pointer_shape_tests_driver.c: ... this; format + with gcc style. + +2025-08-06 Jakub Jelinek <jakub@redhat.com> + + PR preprocessor/120778 + * c-c++-common/cpp/comment-ff-1.c: New test. + * c-c++-common/cpp/comment-vtab-1.c: New test. + +2025-08-06 Martin Uecker <uecker@tugraz.at> + + PR c/121217 + * gcc.dg/pr121217.c: New test. + +2025-08-06 Kito Cheng <kito.cheng@sifive.com> + + * gcc.target/riscv/arch-unset-1.c: New test. + * gcc.target/riscv/arch-unset-2.c: New test. + * gcc.target/riscv/arch-unset-3.c: New test. + * gcc.target/riscv/arch-unset-4.c: New test. + * gcc.target/riscv/arch-unset-5.c: New test. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * c-c++-common/gomp/target-update-iterators-1.c: New. + * c-c++-common/gomp/target-update-iterators-2.c: New. + * c-c++-common/gomp/target-update-iterators-3.c: New. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + Andrew Stubbs <ams@baylibre.com> + + * c-c++-common/gomp/map-6.c (foo): Amend expected error message. + * c-c++-common/gomp/target-map-iterators-1.c: New. + * c-c++-common/gomp/target-map-iterators-2.c: New. + * c-c++-common/gomp/target-map-iterators-3.c: New. + * c-c++-common/gomp/target-map-iterators-4.c: New. + +2025-08-06 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libfortran/121234 + * gfortran.dg/pr121234.f90: New test. + 2025-08-05 Jason Merrill <jason@redhat.com> PR c++/121068 diff --git a/gcc/testsuite/g++.dg/DRs/dr2575.C b/gcc/testsuite/g++.dg/DRs/dr2575.C new file mode 100644 index 0000000..f350282 --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2575.C @@ -0,0 +1,51 @@ +// DR 2575 - Undefined behavior when macro-replacing "defined" operator +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } + +#define A defined +#if !A(A) // { dg-error "this use of 'defined' may not be portable" } +#error +#endif +#if A(B) // { dg-error "this use of 'defined' may not be portable" } +#error +#endif +#if !A A // { dg-error "this use of 'defined' may not be portable" } +#error +#endif +#if A B // { dg-error "this use of 'defined' may not be portable" } +#error +#endif +#if defined A + B +#else +#error +#endif +#if defined +B // { dg-error "operator 'defined' requires an identifier" } +#endif // { dg-error "missing binary operator before token 'B'" "" { target *-*-* } .-1 } +#if defined 1 // { dg-error "operator 'defined' requires an identifier" } +#endif +#if defined // { dg-error "operator 'defined' requires an identifier" } +#endif +#if defined (A + B) // { dg-error "missing '\\\)' after 'defined'" } +#endif // { dg-error "missing binary operator before token 'B'" "" { target *-*-* } .-1 } +#if defined (+B) // { dg-error "operator 'defined' requires an identifier" } +#endif // { dg-error "missing binary operator before token 'B'" "" { target *-*-* } .-1 } +#if defined (1) // { dg-error "operator 'defined' requires an identifier" } +#endif // { dg-error "missing '\\\(' in expression" "" { target *-*-* } .-1 } +#if defined () // { dg-error "operator 'defined' requires an identifier" } +#endif +#if defined A, B // { dg-error "comma operator in operand of #if" } +#endif +#if defined (A), B // { dg-error "comma operator in operand of #if" } +#endif +#if (defined A), B // { dg-error "comma operator in operand of #if" } +#endif +#if defined (A, B) // { dg-error "missing '\\\)' after 'defined'" } +#endif // { dg-error "missing binary operator before token 'B'" "" { target *-*-* } .-1 } +#if defined (A) + B +#else +#error +#endif +#if (defined A) + B +#else +#error +#endif diff --git a/gcc/testsuite/g++.dg/DRs/dr2576.C b/gcc/testsuite/g++.dg/DRs/dr2576.C new file mode 100644 index 0000000..ed53a08 --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2576.C @@ -0,0 +1,47 @@ +// DR 2576 - Undefined behavior with macro-expanded #include directives +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } + +#define A <cstddef> +#include A +#define B "cstddef" +#include B +#define C(x) #x +#define D(x) C(x) +#include D(cstddef) +#include "cstddef" "" // { dg-error "extra tokens at end of '#include' directive" } +#include "cstddef"".h" // { dg-error "extra tokens at end of '#include' directive" } +#include // { dg-error "'#include' expects '\"FILENAME\"' or '<FILENAME>'" } +#include E // { dg-error "'#include' expects '\"FILENAME\"' or '<FILENAME>'" } +#include <cstddef + // { dg-error "missing terminating '>' character" "" { target *-*-* } .-1 } +#include "cstddef + // { dg-error "missing terminating \" character" "" { target *-*-* } .-1 } + // { dg-error "'#include' expects '\"FILENAME\"' or '<FILENAME>'" "" { target *-*-* } .-2 } +#define F cstddef +#include F // { dg-error "'#include' expects '\"FILENAME\"' or '<FILENAME>'" } +// There is implementation divergence on the following cases (G H through M N) +// between e.g. GCC and clang++. clang++ fails on trying to include ' cstddef' +// and 'cstd def' and 'stddef .h' and 'cstddef ' headers. +// https://eel.is/c++draft/cpp.include#7.sentence-3 makes the whitespace +// handling implementation defined and the way GCC handles it can allow +// certain use cases which aren't otherwise possible. One can still +// insert spaces into the <> filenames if it is from the same macro. +#define G < +#define H cstddef> +#include G H +#define I <cstd +#define J def> +#include I J +#define K <stddef +#define L .h> +#include K L +#define M <cstddef +#define N > +#include M N +#define O <cstddef> <cstddef> +#include O // { dg-error "extra tokens at end of '#include' directive" } +#define P "cstddef" "" +#include P // { dg-error "extra tokens at end of '#include' directive" } +#define Q "cstddef"".h" +#include Q // { dg-error "extra tokens at end of '#include' directive" } diff --git a/gcc/testsuite/g++.dg/DRs/dr2577-1.C b/gcc/testsuite/g++.dg/DRs/dr2577-1.C new file mode 100644 index 0000000..784b6a8 --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2577-1.C @@ -0,0 +1,40 @@ +// DR 2577 - Undefined behavior for preprocessing directives in macro arguments +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } + +#define A(x) +#define B(x, y) +A( +#if 1 // { dg-error "embedding a directive within macro arguments is not portable" } +1 +#else // { dg-error "embedding a directive within macro arguments is not portable" } +2 +#endif // { dg-error "embedding a directive within macro arguments is not portable" } +) +B(1, +#line 234 // { dg-error "embedding a directive within macro arguments is not portable" } +) +#line 18 +A( +#define C 1 // { dg-error "embedding a directive within macro arguments is not portable" } +) +A( +#undef C // { dg-error "embedding a directive within macro arguments is not portable" } +) +B(42, +# 234 "dr2577-1.C" // { dg-error "embedding a directive within macro arguments is not portable" } +) // { dg-error "style of line directive is a GCC extension" "" { target *-*-* } .-1 } +#line 28 "dr2577-1.C" +B( +#warning "foobar" // { dg-error "embedding a directive within macro arguments is not portable" } +, 12) // { dg-error "'#warning' before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } .-1 } + // { dg-warning "#warning \"foobar\"" "" { target *-*-* } .-2 } +A( +#pragma GCC diagnostics push // { dg-error "embedding a directive within macro arguments is not portable" } +) +B(5, +#pragma GCC diagnostics pop // { dg-error "embedding a directive within macro arguments is not portable" } +) +A( +#error foobar // { dg-error "embedding a directive within macro arguments is not portable" } +) // { dg-error "#error foobar" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/g++.dg/DRs/dr2577-2.C b/gcc/testsuite/g++.dg/DRs/dr2577-2.C new file mode 100644 index 0000000..e54006a --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2577-2.C @@ -0,0 +1,13 @@ +// DR 2577 - Undefined behavior for preprocessing directives in macro arguments +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } + +#define A(x, y, z) x + y + z +int a = A( +#include "dr2577-2.h" // { dg-error "embedding a directive within macro arguments is not portable" } +, +#include "dr2577-2.h" +, +#include "dr2577-2.h" +); +// { dg-error "unterminated argument list invoking macro 'A'" "" { target *-*-* } 0 } diff --git a/gcc/testsuite/g++.dg/DRs/dr2577-2.h b/gcc/testsuite/g++.dg/DRs/dr2577-2.h new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2577-2.h @@ -0,0 +1 @@ +1 diff --git a/gcc/testsuite/g++.dg/DRs/dr2577-3.C b/gcc/testsuite/g++.dg/DRs/dr2577-3.C new file mode 100644 index 0000000..6ebf419 --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2577-3.C @@ -0,0 +1,7 @@ +// DR 2577 - Undefined behavior for preprocessing directives in macro arguments +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } + +#define A(x) x +int a = A( +#include "dr2577-3.h" // { dg-error "embedding a directive within macro arguments is not portable" } diff --git a/gcc/testsuite/g++.dg/DRs/dr2577-3.h b/gcc/testsuite/g++.dg/DRs/dr2577-3.h new file mode 100644 index 0000000..5e36ce0 --- /dev/null +++ b/gcc/testsuite/g++.dg/DRs/dr2577-3.h @@ -0,0 +1 @@ +1) diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-new3.C b/gcc/testsuite/g++.dg/cpp26/constexpr-new3.C index 7466199..c79060f 100644 --- a/gcc/testsuite/g++.dg/cpp26/constexpr-new3.C +++ b/gcc/testsuite/g++.dg/cpp26/constexpr-new3.C @@ -37,7 +37,7 @@ baz () { std::allocator<int> a; auto b = a.allocate (2); - new (b) long (42); // { dg-error "accessing value of 'int [2]' object through a 'long int' glvalue in a constant expression" } + new (b) long (42); // { dg-error "accessing value of 'int \\\[2\\\]' object through a 'long int' glvalue in a constant expression" } a.deallocate (b, 2); return true; } diff --git a/gcc/testsuite/g++.dg/cpp26/decomp13.C b/gcc/testsuite/g++.dg/cpp26/decomp13.C new file mode 100644 index 0000000..d01590f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp13.C @@ -0,0 +1,52 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do compile { target c++11 } } +// { dg-options "" } + +namespace std { + template<typename T> struct tuple_size; + template<int, typename> struct tuple_element; +} + +struct S { int a, b, c, d; }; +struct T { + int a[5]; + template <int I> int &get () { return a[I]; } +}; + +template<> struct std::tuple_size<T> { static const int value = 5; }; +template<int I> struct std::tuple_element<I,T> { using type = int; }; + +template <int N> +void +foo () +{ + auto [a, ...b, c] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + auto [...d] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + auto [...e, f, ...g, h] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-error "multiple packs in structured binding declaration" "" { target *-*-* } .-2 } + auto [i, j, k, l, ...m, n] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-error "6 names provided for structured binding" "" { target *-*-* } .-2 } + // { dg-message "while 'S' decomposes into 4 elements" "" { target *-*-* } .-3 } + auto [o, ...p, q, r, s] = S (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + auto [t, u, v, w, x, ...y, z] = T (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-error "7 names provided for structured binding" "" { target *-*-* } .-2 } + // { dg-message "while 'T' decomposes into 5 elements" "" { target *-*-* } .-3 } + int aa[] = { 1, 2, 3 }; + const auto & [ab, ...ac, ad, ae, af] = aa; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-error "5 names provided for structured binding" "" { target *-*-* } .-2 } + // { dg-message "while 'const int \\\[3\\\]' decomposes into 3 elements" "" { target *-*-* } .-3 } +} + +void +bar () +{ + auto [a, ...b, c, d] = S (); // { dg-error "structured binding pack outside of template" } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } +} diff --git a/gcc/testsuite/g++.dg/cpp26/decomp14.C b/gcc/testsuite/g++.dg/cpp26/decomp14.C new file mode 100644 index 0000000..f626ec9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp14.C @@ -0,0 +1,474 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do run { target c++11 } } +// { dg-options "" } + +struct S { + int a; long long b; short c; + explicit operator bool () const noexcept { return true; } +}; +namespace std { + template <typename T> struct tuple_size; + template <int, typename> struct tuple_element; +} +struct T { + short c; int a; long long b; + template <int I> + typename std::tuple_element<I, T>::type &get (); + template <int I> + typename std::tuple_element<I, const T>::type &get () const; + explicit operator bool () const noexcept { return false; } +}; +template <> +struct std::tuple_size<T> { static constexpr int value = 3; }; +template <> +struct std::tuple_element<0, T> { typedef int type; }; +template <> +struct std::tuple_element<1, T> { typedef long long type; }; +template <> +struct std::tuple_element<2, T> { typedef short type; }; +template <> +std::tuple_element<0, T>::type &T::get <0> () { return a; } +template <> +std::tuple_element<1, T>::type &T::get <1> () { return b; } +template <> +std::tuple_element<2, T>::type &T::get <2> () { return c; } +template <> +struct std::tuple_size<const T> { static constexpr int value = 3; }; +template <> +struct std::tuple_element<0, const T> { typedef const int type; }; +template <> +struct std::tuple_element<1, const T> { typedef const long long type; }; +template <> +struct std::tuple_element<2, const T> { typedef const short type; }; +template <> +std::tuple_element<0, const T>::type &T::get <0> () const { return a; } +template <> +std::tuple_element<1, const T>::type &T::get <1> () const { return b; } +template <> +std::tuple_element<2, const T>::type &T::get <2> () const { return c; } +template <typename T, typename U> +struct same_type { static const bool value = false; }; +template <typename T> +struct same_type<T, T> { static const bool value = true; }; + +int +sum () +{ + return 0; +} + +template <typename T, typename ...A> +T +sum (T x, A... y) +{ + return x + sum (y...); +} + +template <typename T> +T +square (T x) +{ + return x * x; +} + +template <typename T> +T & +ref (T &x) +{ + return x; +} + +using size_t = decltype (sizeof 0); + +template <int N> +size_t +foo () +{ + S s = S { 1, 2, 3 }; + auto [sa, sb, sc] = S { 1, 2, 3 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + static_assert (same_type <decltype (sa), int>::value, ""); + static_assert (same_type <decltype (sb), long long>::value, ""); + static_assert (same_type <decltype (sc), short>::value, ""); + auto [sd, ...se] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + constexpr size_t ses = sizeof... (se); + static_assert (sizeof... (se) == 2, ""); + static_assert (same_type <decltype (sd), int>::value, ""); + static_assert (same_type <decltype (se...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (se...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + const auto & [...sf [[]], sg] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sf) == 2, ""); + static_assert (same_type <decltype (sf...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sf...[1]), const long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sg), const short>::value, ""); + auto [sh, si, sj [[]], ...sk] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sk) == 0, ""); + static_assert (same_type <decltype (sh), int>::value, ""); + static_assert (same_type <decltype (si), long long>::value, ""); + static_assert (same_type <decltype (sj), short>::value, ""); + auto && [sl, ...sm [[maybe_unused]], sn] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sm) == 1, ""); + static_assert (same_type <decltype (sl), int>::value, ""); + static_assert (same_type <decltype (sm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sn), short>::value, ""); + auto [...so] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (so) == 3, ""); + static_assert (same_type <decltype (so...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (so...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (so...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...sp, sq, sr, ss [[maybe_unused]]] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sp) == 0, ""); + static_assert (same_type <decltype (sq), int>::value, ""); + static_assert (same_type <decltype (sr), long long>::value, ""); + static_assert (same_type <decltype (ss), short>::value, ""); + auto [st, ...su, sv, sw] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (su) == 0, ""); + static_assert (same_type <decltype (st), int>::value, ""); + static_assert (same_type <decltype (sv), long long>::value, ""); + static_assert (same_type <decltype (sw), short>::value, ""); + if (sa != 1 || sb != 2 || sc != 3 + || sd != 1 || se...[0] != 2 || se...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sf...[0] != 1 || sf...[1] != 2 || sg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sh != 1 || si != 2 || sj != 3 + || sl != 1 || sm...[0] != 2 || sn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || so...[0] != 1 || so...[1] != 2 || so...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sq != 1 || sr != 2 || ss != 3 + || st != 1 || sv != 2 || sw != 3 + || sum (se...) != 5 + || sum <decltype (se)...> (se...) != 5 + || sum (square (square (se))...) != 97 + || sum (sf...) != 3 + || sum (sk...) != 0 + || sum (sm...) != 2 + || sum (so...) != 6 + || sum <decltype (so)...> (so...) != 6 + || sum (square (so)...) != 14 + || sum (sp...) != 0 + || sum (su...) != 0 + || (se + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + sf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + sk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (sm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (so + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (sp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + su) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + S s2[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; + int i = 0; + for (auto [sx, ...sy [[]]] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sy) == 2, ""); + static_assert (same_type <decltype (sx), int>::value, ""); + static_assert (same_type <decltype (sy...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sy...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (sx != i * 3 + 1 || sum (sy...) != i * 6 + 5) + __builtin_abort (); + auto fn1 = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn1 (); + auto fn2 = [&sy..., &i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn2 (); + auto fn3 = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn4 = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn5 = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn5 (); + auto fn6 = [sy..., i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn6 (); + auto fn7 = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn8 = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn9 = [&] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn9 (); + auto fn10 = [&sy..., &i] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn10 (); + auto fn11 = [&] () { auto fn = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + auto fn12 = [&sy..., &i] () { auto fn = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + auto fn13 = [=] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn13 (); + auto fn14 = [sy..., i] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn14 (); + auto fn15 = [=] () { auto fn = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + auto fn16 = [&sy..., &i] () { auto fn = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + ++i; + } + i = 0; + for (auto [...sz] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (sz) == 3, ""); + static_assert (same_type <decltype (sz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (sum (sz...) != i * 9 + 6) + __builtin_abort (); + auto fn = [=] () { if (sum (sz...) != i * 9 + 6) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn (); + ++i; + } + if (auto [...sx, sy] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } } + { + static_assert (sizeof... (sx) == 2, ""); + static_assert (same_type <decltype (sx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sy), short>::value, ""); + if (sum (sx...) != 3 || sy != 3) + __builtin_abort (); + } + else + __builtin_abort (); + T t = T { 3, 1, 2 }; + auto [ta, tb, tc] = T { 3, 1, 2 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + static_assert (same_type <decltype (ta), int>::value, ""); + static_assert (same_type <decltype (tb), long long>::value, ""); + static_assert (same_type <decltype (tc), short>::value, ""); + auto [td [[maybe_unused]], ...te] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (te) == 2, ""); + static_assert (same_type <decltype (td), int>::value, ""); + static_assert (same_type <decltype (te...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (te...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...tf [[maybe_unused]], tg] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (tf) == 2, ""); + static_assert (same_type <decltype (tf...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tf...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tg), short>::value, ""); + const auto & [th, ti, tj, ...tk] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (tk) == 0, ""); + static_assert (same_type <decltype (th), const int>::value, ""); + static_assert (same_type <decltype (ti), const long long>::value, ""); + static_assert (same_type <decltype (tj), const short>::value, ""); + auto [tl [[]], ...tm [[]], tn [[]]] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (tm) == 1, ""); + static_assert (same_type <decltype (tl), int>::value, ""); + static_assert (same_type <decltype (tm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tn), short>::value, ""); + auto && [...to] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (to) == 3, ""); + static_assert (same_type <decltype (to...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (to...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (to...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...tp, tq [[]], tr, ts] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (tp) == 0, ""); + static_assert (same_type <decltype (tq), int>::value, ""); + static_assert (same_type <decltype (tr), long long>::value, ""); + static_assert (same_type <decltype (ts), short>::value, ""); + auto [tt, ...tu [[]], tv, tw] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (tu) == 0, ""); + static_assert (same_type <decltype (tt), int>::value, ""); + static_assert (same_type <decltype (tv), long long>::value, ""); + static_assert (same_type <decltype (tw), short>::value, ""); + if (ta != 1 || tb != 2 || tc != 3 + || td != 1 || te...[0] != 2 || te...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || tf...[0] != 1 || tf...[1] != 2 || tg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || th != 1 || ti != 2 || tj != 3 + || tl != 1 || tm...[0] != 2 || tn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || to...[0] != 1 || to...[1] != 2 || to...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } } + || tq != 1 || tr != 2 || ts != 3 + || tt != 1 || tv != 2 || tw != 3 + || sum (te...) != 5 + || sum <decltype (te)...> (te...) != 5 + || sum (square (square (te))...) != 97 + || sum (tf...) != 3 + || sum (tk...) != 0 + || sum (tm...) != 2 + || sum (to...) != 6 + || sum <decltype (to)...> (to...) != 6 + || sum (square (to)...) != 14 + || sum (tp...) != 0 + || sum (tu...) != 0 + || (te + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + tf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + tk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (tm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (to + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (tp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + tu) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + T t2[] = { { 3, 1, 2 }, { 6, 4, 5 }, { 9, 7, 8 } }; + i = 0; + for (auto [tx, ...ty] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ty) == 2, ""); + static_assert (same_type <decltype (tx), int>::value, ""); + static_assert (same_type <decltype (ty...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ty...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (tx != i * 3 + 1 || sum (ty...) != i * 6 + 5) + __builtin_abort (); + auto fn1 = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; + fn1 (); + auto fn2 = [&ty..., &i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn2 (); + auto fn3 = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn4 = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn5 = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; + fn5 (); + auto fn6 = [ty..., i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn6 (); + auto fn7 = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn8 = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn9 = [&] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; + fn9 (); + auto fn10 = [&ty..., &i] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn10 (); + auto fn11 = [&] () { auto fn = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn12 = [&ty..., &i] () { auto fn = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + auto fn13 = [=] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; + fn13 (); + auto fn14 = [ty..., i] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn14 (); + auto fn15 = [=] () { auto fn = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn16 = [&ty..., &i] () { auto fn = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + ++i; + } + i = 0; + for (auto [...tz] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (tz) == 3, ""); + static_assert (same_type <decltype (tz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (sum (tz...) != i * 9 + 6) + __builtin_abort (); + auto fn = [=] () { if (sum (tz...) != i * 9 + 6) __builtin_abort (); }; + fn (); + ++i; + } + if (auto [...tx [[maybe_unused]], ty] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } } + __builtin_abort (); + else + { + static_assert (sizeof... (tx) == 2, ""); + static_assert (same_type <decltype (tx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ty), short>::value, ""); + if (sum (tx...) != 3 || ty != 3) + __builtin_abort (); + } + int a[3] = { 1, 2, 3 }; + auto [aa, ab, ac] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + static_assert (same_type <decltype (aa), int>::value, ""); + static_assert (same_type <decltype (ab), int>::value, ""); + static_assert (same_type <decltype (ac), int>::value, ""); + auto [ad [[maybe_unused]], ...ae [[maybe_unused]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (ae) == 2, ""); + static_assert (same_type <decltype (ad), int>::value, ""); + static_assert (same_type <decltype (ae...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ae...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...af, ag] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (af) == 2, ""); + static_assert (same_type <decltype (af...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (af...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ag), int>::value, ""); + auto [ah, ai [[]], aj, ...ak [[]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (ak) == 0, ""); + static_assert (same_type <decltype (ah), int>::value, ""); + static_assert (same_type <decltype (ai), int>::value, ""); + static_assert (same_type <decltype (aj), int>::value, ""); + auto [al, ...am [[]], an] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (am) == 1, ""); + static_assert (same_type <decltype (al), int>::value, ""); + static_assert (same_type <decltype (am...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (an), int>::value, ""); + const auto &[...ao] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ao) == 3, ""); + static_assert (same_type <decltype (ao...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ao...[1]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ao...[2]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto &&[...ap, aq, ar [[]], as] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (ap) == 0, ""); + static_assert (same_type <decltype (aq), int>::value, ""); + static_assert (same_type <decltype (ar), int>::value, ""); + static_assert (same_type <decltype (as), int>::value, ""); + auto [at, ...au, av, aw] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (au) == 0, ""); + static_assert (same_type <decltype (at), int>::value, ""); + static_assert (same_type <decltype (av), int>::value, ""); + static_assert (same_type <decltype (aw), int>::value, ""); + if (aa != 1 || ab != 2 || ac != 3 + || ad != 1 || ae...[0] != 2 || ae...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || af...[0] != 1 || af...[1] != 2 || ag != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || ah != 1 || ai != 2 || aj != 3 + || al != 1 || am...[0] != 2 || an != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || ao...[0] != 1 || ao...[1] != 2 || ao...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } } + || aq != 1 || ar != 2 || as != 3 + || at != 1 || av != 2 || aw != 3 + || sum (ae...) != 5 + || sum <decltype (ae)...> (ae...) != 5 + || sum (square (square (ae))...) != 97 + || sum (af...) != 3 + || sum (ak...) != 0 + || sum (am...) != 2 + || sum (ao...) != 6 + || sum <decltype (ao)...> (ao...) != 6 + || sum (square (ao)...) != 14 + || sum (ap...) != 0 + || sum (au...) != 0 + || (ae + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + af) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + ak) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (am + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (ao + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (ap + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + au) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + return ses; +} + +int +main () +{ + if (foo <0> () != 2) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp26/decomp15.C b/gcc/testsuite/g++.dg/cpp26/decomp15.C new file mode 100644 index 0000000..9bb55b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp15.C @@ -0,0 +1,474 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do run { target c++11 } } +// { dg-options "" } + +struct S { + int a; long long b; short c; + explicit operator bool () const noexcept { return true; } +}; +namespace std { + template <typename T> struct tuple_size; + template <int, typename> struct tuple_element; +} +struct T { + short c; int a; long long b; + template <int I> + typename std::tuple_element<I, T>::type &get (); + template <int I> + typename std::tuple_element<I, const T>::type &get () const; + explicit operator bool () const noexcept { return false; } +}; +template <> +struct std::tuple_size<T> { static constexpr int value = 3; }; +template <> +struct std::tuple_element<0, T> { typedef int type; }; +template <> +struct std::tuple_element<1, T> { typedef long long type; }; +template <> +struct std::tuple_element<2, T> { typedef short type; }; +template <> +std::tuple_element<0, T>::type &T::get <0> () { return a; } +template <> +std::tuple_element<1, T>::type &T::get <1> () { return b; } +template <> +std::tuple_element<2, T>::type &T::get <2> () { return c; } +template <> +struct std::tuple_size<const T> { static constexpr int value = 3; }; +template <> +struct std::tuple_element<0, const T> { typedef const int type; }; +template <> +struct std::tuple_element<1, const T> { typedef const long long type; }; +template <> +struct std::tuple_element<2, const T> { typedef const short type; }; +template <> +std::tuple_element<0, const T>::type &T::get <0> () const { return a; } +template <> +std::tuple_element<1, const T>::type &T::get <1> () const { return b; } +template <> +std::tuple_element<2, const T>::type &T::get <2> () const { return c; } +template <typename T, typename U> +struct same_type { static const bool value = false; }; +template <typename T> +struct same_type<T, T> { static const bool value = true; }; + +int +sum () +{ + return 0; +} + +template <typename T, typename ...A> +T +sum (T x, A... y) +{ + return x + sum (y...); +} + +template <typename T> +T +square (T x) +{ + return x * x; +} + +template <typename T> +T & +ref (T &x) +{ + return x; +} + +using size_t = decltype (sizeof 0); + +template <typename S, typename T, typename U> +size_t +foo () +{ + S s = S { 1, 2, 3 }; + auto [sa, sb, sc] = S { 1, 2, 3 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + static_assert (same_type <decltype (sa), int>::value, ""); + static_assert (same_type <decltype (sb), long long>::value, ""); + static_assert (same_type <decltype (sc), short>::value, ""); + auto [sd, ...se] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (se) == 2, ""); + static_assert (same_type <decltype (sd), int>::value, ""); + static_assert (same_type <decltype (se...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (se...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + const auto & [...sf [[]], sg] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sf) == 2, ""); + static_assert (same_type <decltype (sf...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sf...[1]), const long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sg), const short>::value, ""); + auto [sh, si, sj [[]], ...sk] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sk) == 0, ""); + static_assert (same_type <decltype (sh), int>::value, ""); + static_assert (same_type <decltype (si), long long>::value, ""); + static_assert (same_type <decltype (sj), short>::value, ""); + auto && [sl, ...sm [[maybe_unused]], sn] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sm) == 1, ""); + static_assert (same_type <decltype (sl), int>::value, ""); + static_assert (same_type <decltype (sm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sn), short>::value, ""); + auto [...so] = S { 1, 2, 3 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (so) == 3, ""); + static_assert (same_type <decltype (so...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (so...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (so...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...sp, sq, sr, ss [[maybe_unused]]] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sp) == 0, ""); + static_assert (same_type <decltype (sq), int>::value, ""); + static_assert (same_type <decltype (sr), long long>::value, ""); + static_assert (same_type <decltype (ss), short>::value, ""); + auto [st, ...su, sv, sw] = S { 1, 2, 3 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (su) == 0, ""); + static_assert (same_type <decltype (st), int>::value, ""); + static_assert (same_type <decltype (sv), long long>::value, ""); + static_assert (same_type <decltype (sw), short>::value, ""); + if (sa != 1 || sb != 2 || sc != 3 + || sd != 1 || se...[0] != 2 || se...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sf...[0] != 1 || sf...[1] != 2 || sg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sh != 1 || si != 2 || sj != 3 + || sl != 1 || sm...[0] != 2 || sn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || so...[0] != 1 || so...[1] != 2 || so...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sq != 1 || sr != 2 || ss != 3 + || st != 1 || sv != 2 || sw != 3 + || sum (se...) != 5 + || sum <decltype (se)...> (se...) != 5 + || sum (square (square (se))...) != 97 + || sum (sf...) != 3 + || sum (sk...) != 0 + || sum (sm...) != 2 + || sum (so...) != 6 + || sum <decltype (so)...> (so...) != 6 + || sum (square (so)...) != 14 + || sum (sp...) != 0 + || sum (su...) != 0 + || (se + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + sf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + sk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (sm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (so + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (sp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + su) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + S s2[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; + int i = 0; + for (auto [sx, ...sy [[]]] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (sy) == 2, ""); + static_assert (same_type <decltype (sx), int>::value, ""); + static_assert (same_type <decltype (sy...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sy...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (sx != i * 3 + 1 || sum (sy...) != i * 6 + 5) + __builtin_abort (); + auto fn1 = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn1 (); + auto fn2 = [&sy..., &i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn2 (); + auto fn3 = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn4 = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn5 = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn5 (); + auto fn6 = [sy..., i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn6 (); + auto fn7 = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn8 = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn9 = [&] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn9 (); + auto fn10 = [&sy..., &i] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn10 (); + auto fn11 = [&] () { auto fn = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + auto fn12 = [&sy..., &i] () { auto fn = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + auto fn13 = [=] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn13 (); + auto fn14 = [sy..., i] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn14 (); + auto fn15 = [=] () { auto fn = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + auto fn16 = [&sy..., &i] () { auto fn = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + ++i; + } + i = 0; + for (auto [...sz] : s2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (sz) == 3, ""); + static_assert (same_type <decltype (sz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (sum (sz...) != i * 9 + 6) + __builtin_abort (); + auto fn = [=] () { if (sum (sz...) != i * 9 + 6) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn (); + ++i; + } + if (auto [...sx, sy] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } } + { + static_assert (sizeof... (sx) == 2, ""); + static_assert (same_type <decltype (sx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (sy), short>::value, ""); + if (sum (sx...) != 3 || sy != 3) + __builtin_abort (); + } + else + __builtin_abort (); + T t = T { 3, 1, 2 }; + auto [ta, tb, tc] = T { 3, 1, 2 }; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + static_assert (same_type <decltype (ta), int>::value, ""); + static_assert (same_type <decltype (tb), long long>::value, ""); + static_assert (same_type <decltype (tc), short>::value, ""); + auto [td [[maybe_unused]], ...te] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (te) == 2, ""); + static_assert (same_type <decltype (td), int>::value, ""); + static_assert (same_type <decltype (te...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (te...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...tf [[maybe_unused]], tg] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (tf) == 2, ""); + static_assert (same_type <decltype (tf...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tf...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tg), short>::value, ""); + const auto & [th, ti, tj, ...tk] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (tk) == 0, ""); + static_assert (same_type <decltype (th), const int>::value, ""); + static_assert (same_type <decltype (ti), const long long>::value, ""); + static_assert (same_type <decltype (tj), const short>::value, ""); + auto [tl [[]], ...tm [[]], tn [[]]] = T { 3, 1, 2 }; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (tm) == 1, ""); + static_assert (same_type <decltype (tl), int>::value, ""); + static_assert (same_type <decltype (tm...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tn), short>::value, ""); + auto && [...to] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (to) == 3, ""); + constexpr size_t tos = sizeof... (to); + static_assert (same_type <decltype (to...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (to...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (to...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...tp, tq [[]], tr, ts] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (tp) == 0, ""); + static_assert (same_type <decltype (tq), int>::value, ""); + static_assert (same_type <decltype (tr), long long>::value, ""); + static_assert (same_type <decltype (ts), short>::value, ""); + auto [tt, ...tu [[]], tv, tw] = T { 3, 1, 2 };// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (tu) == 0, ""); + static_assert (same_type <decltype (tt), int>::value, ""); + static_assert (same_type <decltype (tv), long long>::value, ""); + static_assert (same_type <decltype (tw), short>::value, ""); + if (ta != 1 || tb != 2 || tc != 3 + || td != 1 || te...[0] != 2 || te...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || tf...[0] != 1 || tf...[1] != 2 || tg != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || th != 1 || ti != 2 || tj != 3 + || tl != 1 || tm...[0] != 2 || tn != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || to...[0] != 1 || to...[1] != 2 || to...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } } + || tq != 1 || tr != 2 || ts != 3 + || tt != 1 || tv != 2 || tw != 3 + || sum (te...) != 5 + || sum <decltype (te)...> (te...) != 5 + || sum (square (square (te))...) != 97 + || sum (tf...) != 3 + || sum (tk...) != 0 + || sum (tm...) != 2 + || sum (to...) != 6 + || sum <decltype (to)...> (to...) != 6 + || sum (square (to)...) != 14 + || sum (tp...) != 0 + || sum (tu...) != 0 + || (te + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + tf) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + tk) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (tm + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (to + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (tp + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + tu) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + T t2[] = { { 3, 1, 2 }, { 6, 4, 5 }, { 9, 7, 8 } }; + i = 0; + for (auto [tx, ...ty] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ty) == 2, ""); + static_assert (same_type <decltype (tx), int>::value, ""); + static_assert (same_type <decltype (ty...[0]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ty...[1]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (tx != i * 3 + 1 || sum (ty...) != i * 6 + 5) + __builtin_abort (); + auto fn1 = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; + fn1 (); + auto fn2 = [&ty..., &i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn2 (); + auto fn3 = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn3 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn4 = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn4 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn5 = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; + fn5 (); + auto fn6 = [ty..., i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn6 (); + auto fn7 = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn7 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn8 = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn8 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn9 = [&] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; + fn9 (); + auto fn10 = [&ty..., &i] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn10 (); + auto fn11 = [&] () { auto fn = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn11 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn12 = [&ty..., &i] () { auto fn = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn12 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + auto fn13 = [=] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; + fn13 (); + auto fn14 = [ty..., i] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings are" "" { target c++17_down } } + fn14 (); + auto fn15 = [=] () { auto fn = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn15 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + auto fn16 = [&ty..., &i] () { auto fn = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only available with" "" { target c++17_down } } + fn16 (); // { dg-warning "lambda capture initializers only available with" "" { target c++11_only } .-1 } + // { dg-warning "captured structured bindings are" "" { target c++17_down } .-2 } + ++i; + } + i = 0; + for (auto [...tz] : t2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (tz) == 3, ""); + static_assert (same_type <decltype (tz...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tz...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tz...[2]), short>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (sum (tz...) != i * 9 + 6) + __builtin_abort (); + auto fn = [=] () { if (sum (tz...) != i * 9 + 6) __builtin_abort (); }; + fn (); + ++i; + } + if (auto [...tx [[maybe_unused]], ty] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } } + __builtin_abort (); + else + { + static_assert (sizeof... (tx) == 2, ""); + static_assert (same_type <decltype (tx...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (tx...[1]), long long>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ty), short>::value, ""); + if (sum (tx...) != 3 || ty != 3) + __builtin_abort (); + } + U a[3] = { 1, 2, 3 }; + auto [aa, ab, ac] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + static_assert (same_type <decltype (aa), int>::value, ""); + static_assert (same_type <decltype (ab), int>::value, ""); + static_assert (same_type <decltype (ac), int>::value, ""); + auto [ad [[maybe_unused]], ...ae [[maybe_unused]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (ae) == 2, ""); + static_assert (same_type <decltype (ad), int>::value, ""); + static_assert (same_type <decltype (ae...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ae...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...af, ag] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (af) == 2, ""); + static_assert (same_type <decltype (af...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (af...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ag), int>::value, ""); + auto [ah, ai [[]], aj, ...ak [[]]] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (ak) == 0, ""); + static_assert (same_type <decltype (ah), int>::value, ""); + static_assert (same_type <decltype (ai), int>::value, ""); + static_assert (same_type <decltype (aj), int>::value, ""); + auto [al, ...am [[]], an] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (am) == 1, ""); + static_assert (same_type <decltype (al), int>::value, ""); + static_assert (same_type <decltype (am...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (an), int>::value, ""); + const auto &[...ao] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ao) == 3, ""); + static_assert (same_type <decltype (ao...[0]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ao...[1]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ao...[2]), const int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto &&[...ap, aq, ar [[]], as] = a;// { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured bindings with attributed identifiers only available with" "" { target { c++17 && c++23_down } } .-2 } + static_assert (sizeof... (ap) == 0, ""); + static_assert (same_type <decltype (aq), int>::value, ""); + static_assert (same_type <decltype (ar), int>::value, ""); + static_assert (same_type <decltype (as), int>::value, ""); + auto [at, ...au, av, aw] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (au) == 0, ""); + static_assert (same_type <decltype (at), int>::value, ""); + static_assert (same_type <decltype (av), int>::value, ""); + static_assert (same_type <decltype (aw), int>::value, ""); + if (aa != 1 || ab != 2 || ac != 3 + || ad != 1 || ae...[0] != 2 || ae...[1] != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || af...[0] != 1 || af...[1] != 2 || ag != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || ah != 1 || ai != 2 || aj != 3 + || al != 1 || am...[0] != 2 || an != 3 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || ao...[0] != 1 || ao...[1] != 2 || ao...[2] != 3// { dg-warning "pack indexing only available with" "" { target c++23_down } } + || aq != 1 || ar != 2 || as != 3 + || at != 1 || av != 2 || aw != 3 + || sum (ae...) != 5 + || sum <decltype (ae)...> (ae...) != 5 + || sum (square (square (ae))...) != 97 + || sum (af...) != 3 + || sum (ak...) != 0 + || sum (am...) != 2 + || sum (ao...) != 6 + || sum <decltype (ao)...> (ao...) != 6 + || sum (square (ao)...) != 14 + || sum (ap...) != 0 + || sum (au...) != 0 + || (ae + ...) != 5 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + af) != 3 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + ak) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (am + ... + 0) != 2 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (ao + ...) != 6 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (ap + ... + 0) != 0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + au) != 0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + return tos; +} + +int +main () +{ + if (foo <S, T, int> () != 3) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp26/decomp16.C b/gcc/testsuite/g++.dg/cpp26/decomp16.C new file mode 100644 index 0000000..548f9af --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp16.C @@ -0,0 +1,240 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do run { target c++11 } } +// { dg-options "" } + +int +sum () +{ + return 0; +} + +template <typename T, typename ...A> +T +sum (T x, A... y) +{ + return x + sum (y...); +} + +template <typename T> +T +square (T x) +{ + return x * x; +} + +template <typename T, typename U> +struct same_type { static const bool value = false; }; + +template <typename T> +struct same_type<T, T> { static const bool value = true; }; + +typedef int V __attribute__((vector_size (16 * sizeof (int)))); + +template <int N> +void +foo () +{ + V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + auto [...va] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (va) == 16, ""); + static_assert (same_type <decltype (va...[5]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (va...[13]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [vb, ...vc, vd, ve] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (vc) == 13, ""); + static_assert (same_type <decltype (vb), int>::value, ""); + static_assert (same_type <decltype (vc...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vc...[12]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vd), int>::value, ""); + static_assert (same_type <decltype (ve), int>::value, ""); + auto [vf, vg, vh, vi, ...vj] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (vj) == 12, ""); + static_assert (same_type <decltype (vf), int>::value, ""); + static_assert (same_type <decltype (vg), int>::value, ""); + static_assert (same_type <decltype (vh), int>::value, ""); + static_assert (same_type <decltype (vi), int>::value, ""); + static_assert (same_type <decltype (vj...[2]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vj...[10]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (va...[13] != 14 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (va...) != 8 * 17 + || sum (square (va)...) != 1496 + || vb != 1 + || vc...[10] != 12 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (vc...) != 15 * 7 - 1 + || sum <decltype (vc)...> (vc...) != 15 * 7 - 1 + || vd != 15 || ve != 16 + || vf != 1 || vg != 2 || vh != 3 || vi != 4 + || sum (vj...) != 8 * 17 - 10 + || (va + ...) != 8 * 17 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + vc) != 15 * 7 - 1 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + vj) != 8 * 17 - 10) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + V v2[3] = { v, v + 1, v + 2 }; + int i = 0; + for (auto [vk, ...vl, vm] : v2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (vl) == 14, ""); + static_assert (same_type <decltype (vk), int>::value, ""); + static_assert (same_type <decltype (vl...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vl...[9]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vm), int>::value, ""); + if (vk != i + 1 || sum (vl...) != i * 14 + 15 * 8 - 1 || vm != i + 16) + __builtin_abort (); + ++i; + } + _Complex double c = 1.0 + 2.0i; + auto [...ca] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ca) == 2, ""); + static_assert (same_type <decltype (ca...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ca...[1]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [cb, ...cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (cc) == 0, ""); + static_assert (same_type <decltype (cb), double>::value, ""); + static_assert (same_type <decltype (cd), double>::value, ""); + auto [ce, ...cf] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (cf) == 1, ""); + static_assert (same_type <decltype (ce), double>::value, ""); + static_assert (same_type <decltype (cf...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...cg, ch] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (cg) == 1, ""); + static_assert (same_type <decltype (cg...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ch), double>::value, ""); + if (ca...[0] != 1.0 || ca...[1] != 2.0// { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (ca...) != 3.0 + || sum <decltype (ca)...> (ca...) != 3.0 + || sum (square (square (square (ca)))...) != 257.0 + || cb != 1.0 || cd != 2.0 + || ce != 1.0 || cf...[0] != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (cf...) != 2.0 + || cg...[0] != 1.0 || ch != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (cg...) != 1.0 + || (ca + ...) != 3.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0.0 + ... + cc) != 0.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + cf) != 2.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (cg + ... + 0.0) != 1.0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + _Complex float c2[3] = { 1.0f + 2.0fi, 2.0f + 3.0fi, 3.0f + 4.0fi }; + i = 0; + for (auto [...ci] : c2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ci) == 2, ""); + static_assert (same_type <decltype (ci...[0]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ci...[1]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (sum (ci...) != i * 2 + 3.0f) + __builtin_abort (); + ++i; + } +} + +template <typename V, typename C, typename D> +void +bar () +{ + V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + auto [...va] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (va) == 16, ""); + static_assert (same_type <decltype (va...[5]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (va...[13]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [vb, ...vc, vd, ve] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (vc) == 13, ""); + static_assert (same_type <decltype (vb), int>::value, ""); + static_assert (same_type <decltype (vc...[0]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vc...[12]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vd), int>::value, ""); + static_assert (same_type <decltype (ve), int>::value, ""); + auto [vf, vg, vh, vi, ...vj] = v; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (vj) == 12, ""); + static_assert (same_type <decltype (vf), int>::value, ""); + static_assert (same_type <decltype (vg), int>::value, ""); + static_assert (same_type <decltype (vh), int>::value, ""); + static_assert (same_type <decltype (vi), int>::value, ""); + static_assert (same_type <decltype (vj...[2]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vj...[10]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (va...[13] != 14 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (va...) != 8 * 17 + || vb != 1 + || vc...[10] != 12 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (vc...) != 15 * 7 - 1 + || sum <decltype (vc)...> (vc...) != 15 * 7 - 1 + || vd != 15 || ve != 16 + || vf != 1 || vg != 2 || vh != 3 || vi != 4 + || sum (vj...) != 8 * 17 - 10 + || (va + ...) != 8 * 17 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + vc) != 15 * 7 - 1 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0 + ... + vj) != 8 * 17 - 10) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + V v2[3] = { v, v + 1, v + 2 }; + int i = 0; + for (auto [vk, ...vl, vm] : v2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (vl) == 14, ""); + static_assert (same_type <decltype (vk), int>::value, ""); + static_assert (same_type <decltype (vl...[1]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vl...[9]), int>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (vm), int>::value, ""); + if (vk != i + 1 || sum (vl...) != i * 14 + 15 * 8 - 1 || vm != i + 16) + __builtin_abort (); + ++i; + } + C c = 1.0 + 2.0i; + auto [...ca] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ca) == 2, ""); + static_assert (same_type <decltype (ca...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ca...[1]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [cb, ...cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (cc) == 0, ""); + static_assert (same_type <decltype (cb), double>::value, ""); + static_assert (same_type <decltype (cd), double>::value, ""); + auto [ce, ...cf] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (cf) == 1, ""); + static_assert (same_type <decltype (ce), double>::value, ""); + static_assert (same_type <decltype (cf...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + auto [...cg, ch] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (cg) == 1, ""); + static_assert (same_type <decltype (cg...[0]), double>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ch), double>::value, ""); + if (ca...[0] != 1.0 || ca...[1] != 2.0// { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (ca...) != 3.0 + || sum <decltype (ca)...> (ca...) != 3.0 + || cb != 1.0 || cd != 2.0 + || ce != 1.0 || cf...[0] != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (cf...) != 2.0 + || cg...[0] != 1.0 || ch != 2.0 // { dg-warning "pack indexing only available with" "" { target c++23_down } } + || sum (cg...) != 1.0 + || (ca + ...) != 3.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (0.0 + ... + cc) != 0.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (... + cf) != 2.0 // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + || (cg + ... + 0.0) != 1.0) // { dg-warning "fold-expressions only available with" "" { target c++14_down } } + __builtin_abort (); + D c2[3] = { 1.0f + 2.0fi, 2.0f + 3.0fi, 3.0f + 4.0fi }; + i = 0; + for (auto [...ci] : c2) // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + { // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ci) == 2, ""); + static_assert (same_type <decltype (ci...[0]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + static_assert (same_type <decltype (ci...[1]), float>::value, ""); // { dg-warning "pack indexing only available with" "" { target c++23_down } } + if (sum (ci...) != i * 2 + 3.0f) + __builtin_abort (); + ++i; + } +} + +int +main () +{ + foo <0> (); + bar <V, _Complex double, _Complex float> (); +} diff --git a/gcc/testsuite/g++.dg/cpp26/decomp17.C b/gcc/testsuite/g++.dg/cpp26/decomp17.C new file mode 100644 index 0000000..49ad0e2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp17.C @@ -0,0 +1,28 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do compile { target c++11 } } +// { dg-options "" } + +typedef int V __attribute__((vector_size (16 * sizeof (int)))); + +template <int N> +void +foo () +{ + V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + auto [va, vb, vc, vd, ...ve, vf, vg, vh, vi, vj, vk, vl, vm, vn, vo, vp, vq, vr] = v; + // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } .-1 } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 } + // { dg-error "18 names provided for structured binding" "" { target *-*-* } .-3 } + // { dg-message "while '__vector\\\(16\\\) int' decomposes into 16 elements" "" { target *-*-* } .-4 } + _Complex double c = 1.0 + 2.0i; + auto [...ca, cb, cc, cd] = c; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-error "4 names provided for structured binding" "" { target *-*-* } .-2 } + // { dg-message "while '__complex__ double' decomposes into 2 elements" "" { target *-*-* } .-3 } +} + +int +main () +{ + foo <0> (); +} diff --git a/gcc/testsuite/g++.dg/cpp26/decomp18.C b/gcc/testsuite/g++.dg/cpp26/decomp18.C new file mode 100644 index 0000000..86b9bf4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp18.C @@ -0,0 +1,109 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do run { target c++11 } } +// { dg-options "" } + +struct S { int a, b, c; }; +namespace std { + template <typename T> struct tuple_size; + template <int, typename> struct tuple_element; +} +struct T { + int a[3]; + template <int I> + int &get () { return a[2 - I]; } +}; +template <> +struct std::tuple_size<T> { static constexpr int value = 3; }; +template <int N> +struct std::tuple_element<N, T> { typedef int type; }; + +template <int N> +inline int +foo () +{ + static int a[4] = { N, N + 1, N + 2, N + 3 }; + static auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 } + aa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } } + return (... + aa); // { dg-warning "fold-expressions only available with" "" { target c++14_down } } +} + +template <int N> +inline int +bar () +{ + static S s = { N, N + 1, N + 2 }; + static auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 } + sa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } } + return (sa + ...); // { dg-warning "fold-expressions only available with" "" { target c++14_down } } +} + +template <int N> +inline int +baz () +{ + static T t = { { N, N + 1, N + 2 } }; + static auto [ta, ...tb, tc, td] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 } + tc++; + return ((ta + tc + td) + ... + tb); // { dg-warning "fold-expressions only available with" "" { target c++14_down } } +} + +template <int N> +inline int +qux () +{ + thread_local int a[4] = { N, N + 1, N + 2, N + 3 }; + thread_local auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 } + aa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } } + return (... + aa); // { dg-warning "fold-expressions only available with" "" { target c++14_down } } +} + +template <int N> +inline int +freddy () +{ + thread_local S s = { N, N + 1, N + 2 }; + thread_local auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 } + sa...[1]++; // { dg-warning "pack indexing only available with" "" { target c++23_down } } + return (sa + ...); // { dg-warning "fold-expressions only available with" "" { target c++14_down } } +} + +template <int N> +inline int +corge () +{ + thread_local T t = { { N, N + 1, N + 2 } }; + thread_local auto [ta, ...tb, tc, td] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 } + tc++; + return ((ta + tc + td) + ... + tb); // { dg-warning "fold-expressions only available with" "" { target c++14_down } } +} + +int +main () +{ + if (foo <2> () != 15 || foo <2> () != 16 || foo <2> () != 17 + || foo <42> () != 175 || foo <42> () != 176 + || bar <5> () != 19 || bar <5> () != 20 || bar <5> () != 21 + || bar <18> () != 58 || bar <18> () != 59 + || baz <3> () != 13 || baz <3> () != 14 || baz <3> () != 15 + || baz <22> () != 70 || baz <22> () != 71) + __builtin_abort (); + if (qux <2> () != 15 || qux <2> () != 16 || qux <2> () != 17 + || qux <42> () != 175 || qux <42> () != 176 + || freddy <5> () != 19 || freddy <5> () != 20 || freddy <5> () != 21 + || freddy <18> () != 58 || freddy <18> () != 59 + || corge <3> () != 13 || corge <3> () != 14 || corge <3> () != 15 + || corge <22> () != 70 || corge <22> () != 71) + __builtin_abort (); +} diff --git a/gcc/testsuite/g++.dg/cpp26/decomp19.C b/gcc/testsuite/g++.dg/cpp26/decomp19.C new file mode 100644 index 0000000..b4d97a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp19.C @@ -0,0 +1,46 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do compile { target c++11 } } +// { dg-options "" } + +namespace std { + template <typename T> struct tuple_size; + template <int, typename> struct tuple_element; +} +struct T { + int a[3]; + template <int I> + int &get () { return a[2 - I]; } +}; +template <> +struct std::tuple_size<T> { static constexpr int value = 3; }; +template <int N> +struct std::tuple_element<N, T> { typedef int type; }; + +template <int N> +inline void +foo () +{ + static T t = { { N, N + 1, N + 2 } }; + static auto [ta, ...tb, tc] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-2 } + // { dg-message "mangling of structured binding pack elements not implemented yet" "" { target *-*-* } .-3 } +} + +template <int N> +inline void +bar () +{ + thread_local T t = { { N, N + 1, N + 2 } }; + thread_local auto [...ta] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + // { dg-warning "structured binding declaration can be 'thread_local' only in" "" { target c++17_down } .-2 } + // { dg-message "mangling of structured binding pack elements not implemented yet" "" { target *-*-* } .-3 } +} + +int +main () +{ + foo <0> (); + bar <0> (); +} diff --git a/gcc/testsuite/g++.dg/cpp26/decomp20.C b/gcc/testsuite/g++.dg/cpp26/decomp20.C new file mode 100644 index 0000000..5091e13 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp20.C @@ -0,0 +1,53 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct S { + explicit operator bool () const noexcept { return true; } +}; +namespace std { + template <typename T> struct tuple_size; + template <int, typename> struct tuple_element; +} +int x; +struct T { + template <int I> + int &get () { return x; } + explicit operator bool () const noexcept { return false; } +}; +template <> +struct std::tuple_size<T> { static constexpr int value = 0; }; +template <int N> +struct std::tuple_element<N, T> { typedef int type; }; + +template <int N> +void +foo () +{ + int a[0] = {}; + auto [...aa] = a; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (aa) == 0, ""); + S s = {}; + auto [...sa] = s; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (sa) == 0, ""); + T t = {}; + auto [...ta] = t; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (ta) == 0, ""); + if (auto [...sb] = s) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } } + static_assert (sizeof... (sb) == 0, ""); + else + __builtin_abort (); + if (auto [...tb] = t) // { dg-warning "structured bindings in conditions only available with" "" { target c++23_down } } + __builtin_abort (); + else + static_assert (sizeof... (tb) == 0, ""); +} + +int +main () +{ + foo <0> (); +} diff --git a/gcc/testsuite/g++.dg/cpp26/decomp21.C b/gcc/testsuite/g++.dg/cpp26/decomp21.C new file mode 100644 index 0000000..6baa8aa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/decomp21.C @@ -0,0 +1,103 @@ +// P1061R10 - Structured Bindings can introduce a Pack +// { dg-do run { target c++11 } } +// { dg-options "" } + +using size_t = decltype (sizeof 0); + +auto g () -> int (&)[4] +{ + static int a[4] = { 1, 2, 3, 4 }; + return a; +} + +template <size_t N> +void +h (int (&arr)[N]) +{ + auto [a, ...b, c] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (b) == 2, ""); + auto &[f, ...g, h] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (g) == 2, ""); + if (&f != &arr[0] || &h != &arr[3] + || &g...[0] != &arr[1] || &g...[1] != &arr[2]) // { dg-warning "pack indexing only available with" "" { target c++23_down } } + __builtin_abort (); + auto &[...e] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof ... (e) == 4, ""); + if (&e...[0] != &arr[0] || &e...[3] != &arr[3]) // { dg-warning "pack indexing only available with" "" { target c++23_down } } + __builtin_abort (); +} + +struct C { int x, y, z; }; + +template <class T> +void +now_i_know_my () +{ + auto [a, b, c] = C (); // { dg-warning "structured bindings only available with" "" { target c++14_down } } + auto [d, ...e] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (e) == 2, ""); + auto [...f, g] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (f) == 2, ""); + auto [h, i, j, ...k] = C (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (k) == 0, ""); +// auto [l, m, n, o, ...p] = C (); +} + +auto foo () -> int (&)[2] +{ + static int a[2] = { 1, 2 }; + return a; +} + +template <class T> +void +bar () +{ + auto [...a] = foo (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (a) == 2, ""); + auto [b, c, ...d] = foo (); // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + static_assert (sizeof... (d) == 0, ""); +} + +struct D { }; + +void +baz (...) +{ + __builtin_abort (); +} + +template <typename T> +void +qux () +{ + D arr[1] = {}; + auto [...e] = arr; // { dg-warning "structured binding packs only available with" "" { target { c++17 && c++23_down } } } + // { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 } + baz (e...); +} + +int d; + +void +baz (D) +{ + d = 1; +} + +int +main () +{ + h (g ()); + now_i_know_my <int> (); + bar <int> (); + qux <int> (); +} diff --git a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C index cfc5f61..9284bc2 100644 --- a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C +++ b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C @@ -395,8 +395,8 @@ #ifndef __cpp_structured_bindings # error "__cpp_structured_bindings" -#elif __cpp_structured_bindings != 202403 -# error "__cpp_structured_bindings != 202403" +#elif __cpp_structured_bindings != 202411 +# error "__cpp_structured_bindings != 202411" #endif #ifndef __cpp_template_template_args diff --git a/gcc/testsuite/g++.dg/modules/atom-preamble-3.C b/gcc/testsuite/g++.dg/modules/atom-preamble-3.C index 74dba7d..915fa74 100644 --- a/gcc/testsuite/g++.dg/modules/atom-preamble-3.C +++ b/gcc/testsuite/g++.dg/modules/atom-preamble-3.C @@ -1,4 +1,4 @@ -// { dg-additional-options "-fmodules-ts" } +// { dg-additional-options "-fmodules-ts -Wno-keyword-macro" } #define import import import malcolm; // { dg-error "object-like macro" } // { dg-error "failed to read" "" { target *-*-* } 0 } diff --git a/gcc/testsuite/g++.dg/opt/pr82577.C b/gcc/testsuite/g++.dg/opt/pr82577.C index 1a06897..8a4f36d 100644 --- a/gcc/testsuite/g++.dg/opt/pr82577.C +++ b/gcc/testsuite/g++.dg/opt/pr82577.C @@ -3,7 +3,9 @@ #if __cplusplus > 201500L // register is no longer a keyword in C++17. -#define register +#define reg +#else +#define reg register #endif class a { @@ -14,8 +16,8 @@ struct c { int d; a e; } f; -void fn1(register c *g) { - register int *h; +void fn1(reg c *g) { + reg int *h; do (h) = g->e.b() + (g)->d; while (&f); diff --git a/gcc/testsuite/g++.dg/template/sfinae17.C b/gcc/testsuite/g++.dg/template/sfinae17.C index eb043cb..8628726 100644 --- a/gcc/testsuite/g++.dg/template/sfinae17.C +++ b/gcc/testsuite/g++.dg/template/sfinae17.C @@ -1,7 +1,7 @@ // The conversion from D* to B* is ambiguous, but that should not produce // an error, it should remove the first f overload by SFINAE. -#define static_assert(TEST,STR) \ +#define my_static_assert(TEST,STR) \ do { int ar[(TEST)?1:-1]; } while (0); struct B {}; @@ -23,6 +23,6 @@ template <class T> int main() { - static_assert(sizeof f<int>(0) == sizeof(two), ""); - static_assert(sizeof f<B *>(0) == sizeof(two), ""); + my_static_assert(sizeof f<int>(0) == sizeof(two), ""); + my_static_assert(sizeof f<B *>(0) == sizeof(two), ""); } diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-1.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-1.C new file mode 100644 index 0000000..f47de7a --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-1.C @@ -0,0 +1,112 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } +// { dg-additional-options "-fmodules" { target c++20 } } + +// [lex.key] +#define alignas 1 // { dg-error "keyword 'alignas' defined as macro" "" { target c++26 } } +#define alignof 1 // { dg-error "keyword 'alignof' defined as macro" "" { target c++26 } } +#define asm 1 // { dg-error "keyword 'asm' defined as macro" "" { target c++26 } } +#define auto 1 // { dg-error "keyword 'auto' defined as macro" "" { target c++26 } } +#define bool 1 // { dg-error "keyword 'bool' defined as macro" "" { target c++26 } } +#define break 1 // { dg-error "keyword 'break' defined as macro" "" { target c++26 } } +#define case 1 // { dg-error "keyword 'case' defined as macro" "" { target c++26 } } +#define catch 1 // { dg-error "keyword 'catch' defined as macro" "" { target c++26 } } +#define char 1 // { dg-error "keyword 'char' defined as macro" "" { target c++26 } } +#define char16_t 1 // { dg-error "keyword 'char16_t' defined as macro" "" { target c++26 } } +#define char32_t 1 // { dg-error "keyword 'char32_t' defined as macro" "" { target c++26 } } +#define char8_t 1 // { dg-error "keyword 'char8_t' defined as macro" "" { target c++26 } } +#define class 1 // { dg-error "keyword 'class' defined as macro" "" { target c++26 } } +#define co_await 1 // { dg-error "keyword 'co_await' defined as macro" "" { target c++26 } } +#define concept 1 // { dg-error "keyword 'concept' defined as macro" "" { target c++26 } } +#define const 1 // { dg-error "keyword 'const' defined as macro" "" { target c++26 } } +#define const_cast 1 // { dg-error "keyword 'const_cast' defined as macro" "" { target c++26 } } +#define consteval 1 // { dg-error "keyword 'consteval' defined as macro" "" { target c++26 } } +#define constexpr 1 // { dg-error "keyword 'constexpr' defined as macro" "" { target c++26 } } +#define constinit 1 // { dg-error "keyword 'constinit' defined as macro" "" { target c++26 } } +#define continue 1 // { dg-error "keyword 'continue' defined as macro" "" { target c++26 } } +#define contract_assert 1 +#define co_return 1 // { dg-error "keyword 'co_return' defined as macro" "" { target c++26 } } +#define co_yield 1 // { dg-error "keyword 'co_yield' defined as macro" "" { target c++26 } } +#define decltype 1 // { dg-error "keyword 'decltype' defined as macro" "" { target c++26 } } +#define default 1 // { dg-error "keyword 'default' defined as macro" "" { target c++26 } } +#define delete 1 // { dg-error "keyword 'delete' defined as macro" "" { target c++26 } } +#define do 1 // { dg-error "keyword 'do' defined as macro" "" { target c++26 } } +#define double 1 // { dg-error "keyword 'double' defined as macro" "" { target c++26 } } +#define dynamic_cast 1 // { dg-error "keyword 'dynamic_cast' defined as macro" "" { target c++26 } } +#define else 1 // { dg-error "keyword 'else' defined as macro" "" { target c++26 } } +#define enum 1 // { dg-error "keyword 'enum' defined as macro" "" { target c++26 } } +#define explicit 1 // { dg-error "keyword 'explicit' defined as macro" "" { target c++26 } } +#define export 1 // { dg-error "keyword 'export' defined as macro" "" { target c++26 } } +#define extern 1 // { dg-error "keyword 'extern' defined as macro" "" { target c++26 } } +#define false 1 // { dg-error "keyword 'false' defined as macro" "" { target c++26 } } +#define float 1 // { dg-error "keyword 'float' defined as macro" "" { target c++26 } } +#define for 1 // { dg-error "keyword 'for' defined as macro" "" { target c++26 } } +#define friend 1 // { dg-error "keyword 'friend' defined as macro" "" { target c++26 } } +#define goto 1 // { dg-error "keyword 'goto' defined as macro" "" { target c++26 } } +#define if 1 // { dg-error "keyword 'if' defined as macro" "" { target c++26 } } +#define inline 1 // { dg-error "keyword 'inline' defined as macro" "" { target c++26 } } +#define int 1 // { dg-error "keyword 'int' defined as macro" "" { target c++26 } } +#define long 1 // { dg-error "keyword 'long' defined as macro" "" { target c++26 } } +#define mutable 1 // { dg-error "keyword 'mutable' defined as macro" "" { target c++26 } } +#define namespace 1 // { dg-error "keyword 'namespace' defined as macro" "" { target c++26 } } +#define new 1 // { dg-error "keyword 'new' defined as macro" "" { target c++26 } } +#define noexcept 1 // { dg-error "keyword 'noexcept' defined as macro" "" { target c++26 } } +#define nullptr 1 // { dg-error "keyword 'nullptr' defined as macro" "" { target c++26 } } +#define operator 1 // { dg-error "keyword 'operator' defined as macro" "" { target c++26 } } +#define private 1 // { dg-error "keyword 'private' defined as macro" "" { target c++26 } } +#define protected 1 // { dg-error "keyword 'protected' defined as macro" "" { target c++26 } } +#define public 1 // { dg-error "keyword 'public' defined as macro" "" { target c++26 } } +#define register 1 // { dg-error "keyword 'register' defined as macro" "" { target c++26 } } +#define reinterpret_cast 1 // { dg-error "keyword 'reinterpret_cast' defined as macro" "" { target c++26 } } +#define requires 1 // { dg-error "keyword 'requires' defined as macro" "" { target c++26 } } +#define return 1 // { dg-error "keyword 'return' defined as macro" "" { target c++26 } } +#define short 1 // { dg-error "keyword 'short' defined as macro" "" { target c++26 } } +#define signed 1 // { dg-error "keyword 'signed' defined as macro" "" { target c++26 } } +#define sizeof 1 // { dg-error "keyword 'sizeof' defined as macro" "" { target c++26 } } +#define static 1 // { dg-error "keyword 'static' defined as macro" "" { target c++26 } } +#define static_assert 1 // { dg-error "keyword 'static_assert' defined as macro" "" { target c++26 } } +#define static_cast 1 // { dg-error "keyword 'static_cast' defined as macro" "" { target c++26 } } +#define struct 1 // { dg-error "keyword 'struct' defined as macro" "" { target c++26 } } +#define switch 1 // { dg-error "keyword 'switch' defined as macro" "" { target c++26 } } +#define template 1 // { dg-error "keyword 'template' defined as macro" "" { target c++26 } } +#define this 1 // { dg-error "keyword 'this' defined as macro" "" { target c++26 } } +#define thread_local 1 // { dg-error "keyword 'thread_local' defined as macro" "" { target c++26 } } +#define throw 1 // { dg-error "keyword 'throw' defined as macro" "" { target c++26 } } +#define true 1 // { dg-error "keyword 'true' defined as macro" "" { target c++26 } } +#define try 1 // { dg-error "keyword 'try' defined as macro" "" { target c++26 } } +#define typedef 1 // { dg-error "keyword 'typedef' defined as macro" "" { target c++26 } } +#define typeid 1 // { dg-error "keyword 'typeid' defined as macro" "" { target c++26 } } +#define typename 1 // { dg-error "keyword 'typename' defined as macro" "" { target c++26 } } +#define union 1 // { dg-error "keyword 'union' defined as macro" "" { target c++26 } } +#define unsigned 1 // { dg-error "keyword 'unsigned' defined as macro" "" { target c++26 } } +#define using 1 // { dg-error "keyword 'using' defined as macro" "" { target c++26 } } +#define virtual 1 // { dg-error "keyword 'virtual' defined as macro" "" { target c++26 } } +#define void 1 // { dg-error "keyword 'void' defined as macro" "" { target c++26 } } +#define volatile 1 // { dg-error "keyword 'volatile' defined as macro" "" { target c++26 } } +#define wchar_t 1 // { dg-error "keyword 'wchar_t' defined as macro" "" { target c++26 } } +#define while 1 // { dg-error "keyword 'while' defined as macro" "" { target c++26 } } + +// [lex.name] +#define final 1 // { dg-error "keyword 'final' defined as macro" "" { target c++26 } } +#define import 1 // { dg-error "keyword 'import' defined as macro" "" { target c++26 } } +#define module 1 // { dg-error "keyword 'module' defined as macro" "" { target c++26 } } +#define override 1 // { dg-error "keyword 'override' defined as macro" "" { target c++26 } } +#define post 1 +#define pre 1 +#define replaceable_if_eligible 1 // { dg-error "keyword 'replaceable_if_eligible' defined as macro" "" { target c++26 } } +#define trivially_relocatable_if_eligible 1 // { dg-error "keyword 'trivially_relocatable_if_eligible' defined as macro" "" { target c++26 } } + +// [dcl.attr] +#define assume 1 // { dg-error "keyword 'assume' defined as macro" "" { target c++26 } } +#define carries_dependency 1 +#define deprecated 1 // { dg-error "keyword 'deprecated' defined as macro" "" { target c++26 } } +#define fallthrough 1 // { dg-error "keyword 'fallthrough' defined as macro" "" { target c++26 } } +#define indeterminate 1 +#define likely 1 // { dg-error "keyword 'likely' defined as macro" "" { target c++26 } } +#define maybe_unused 1 // { dg-error "keyword 'maybe_unused' defined as macro" "" { target c++26 } } +#define nodiscard 1 // { dg-error "keyword 'nodiscard' defined as macro" "" { target c++26 } } +#define noreturn 1 // { dg-error "keyword 'noreturn' defined as macro" "" { target c++26 } } +#define no_unique_address 1 // { dg-error "keyword 'no_unique_address' defined as macro" "" { target c++26 } } +#define unlikely 1 // { dg-error "keyword 'unlikely' defined as macro" "" { target c++26 } } diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-10.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-10.C new file mode 100644 index 0000000..e6fafcd --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-10.C @@ -0,0 +1,23 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "-Wkeyword-macro" } + +#undef for // { dg-warning "undefining keyword 'for'" } +#define for for // { dg-warning "keyword 'for' defined as macro" } +#undef for // { dg-warning "undefining keyword 'for'" } +#define while do // { dg-warning "keyword 'while' defined as macro" } +#define while do // { dg-warning "keyword 'while' defined as macro" } +#define while for // { dg-warning "keyword 'while' defined as macro" } + // { dg-warning "'while' redefined" "" { target *-*-* } .-1 } +#undef while // { dg-warning "undefining keyword 'while'" } +#define while while // { dg-warning "keyword 'while' defined as macro" } +#define private public // { dg-warning "keyword 'private' defined as macro" } +#define inline // { dg-warning "keyword 'inline' defined as macro" } +#undef inline // { dg-warning "undefining keyword 'inline'" } +#define inline __inline__ __attribute__((__always_inline__)) // { dg-warning "keyword 'inline' defined as macro" } +#define likely(a) a +#undef likely // { dg-warning "undefining keyword 'likely'" "" { target c++20 } } +#define unlikely(a, b, c) a + b + c +#define unlikely(a, b, c) a + b + c +#undef unlikely // { dg-warning "undefining keyword 'unlikely'" "" { target c++20 } } diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-2.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-2.C new file mode 100644 index 0000000..b1a9aa2 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-2.C @@ -0,0 +1,112 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "-pedantic" } +// { dg-additional-options "-fmodules" { target c++20 } } + +// [lex.key] +#define alignas 1 // { dg-warning "keyword 'alignas' defined as macro" "" { target c++26 } } +#define alignof 1 // { dg-warning "keyword 'alignof' defined as macro" "" { target c++26 } } +#define asm 1 // { dg-warning "keyword 'asm' defined as macro" "" { target c++26 } } +#define auto 1 // { dg-warning "keyword 'auto' defined as macro" "" { target c++26 } } +#define bool 1 // { dg-warning "keyword 'bool' defined as macro" "" { target c++26 } } +#define break 1 // { dg-warning "keyword 'break' defined as macro" "" { target c++26 } } +#define case 1 // { dg-warning "keyword 'case' defined as macro" "" { target c++26 } } +#define catch 1 // { dg-warning "keyword 'catch' defined as macro" "" { target c++26 } } +#define char 1 // { dg-warning "keyword 'char' defined as macro" "" { target c++26 } } +#define char16_t 1 // { dg-warning "keyword 'char16_t' defined as macro" "" { target c++26 } } +#define char32_t 1 // { dg-warning "keyword 'char32_t' defined as macro" "" { target c++26 } } +#define char8_t 1 // { dg-warning "keyword 'char8_t' defined as macro" "" { target c++26 } } +#define class 1 // { dg-warning "keyword 'class' defined as macro" "" { target c++26 } } +#define co_await 1 // { dg-warning "keyword 'co_await' defined as macro" "" { target c++26 } } +#define concept 1 // { dg-warning "keyword 'concept' defined as macro" "" { target c++26 } } +#define const 1 // { dg-warning "keyword 'const' defined as macro" "" { target c++26 } } +#define const_cast 1 // { dg-warning "keyword 'const_cast' defined as macro" "" { target c++26 } } +#define consteval 1 // { dg-warning "keyword 'consteval' defined as macro" "" { target c++26 } } +#define constexpr 1 // { dg-warning "keyword 'constexpr' defined as macro" "" { target c++26 } } +#define constinit 1 // { dg-warning "keyword 'constinit' defined as macro" "" { target c++26 } } +#define continue 1 // { dg-warning "keyword 'continue' defined as macro" "" { target c++26 } } +#define contract_assert 1 +#define co_return 1 // { dg-warning "keyword 'co_return' defined as macro" "" { target c++26 } } +#define co_yield 1 // { dg-warning "keyword 'co_yield' defined as macro" "" { target c++26 } } +#define decltype 1 // { dg-warning "keyword 'decltype' defined as macro" "" { target c++26 } } +#define default 1 // { dg-warning "keyword 'default' defined as macro" "" { target c++26 } } +#define delete 1 // { dg-warning "keyword 'delete' defined as macro" "" { target c++26 } } +#define do 1 // { dg-warning "keyword 'do' defined as macro" "" { target c++26 } } +#define double 1 // { dg-warning "keyword 'double' defined as macro" "" { target c++26 } } +#define dynamic_cast 1 // { dg-warning "keyword 'dynamic_cast' defined as macro" "" { target c++26 } } +#define else 1 // { dg-warning "keyword 'else' defined as macro" "" { target c++26 } } +#define enum 1 // { dg-warning "keyword 'enum' defined as macro" "" { target c++26 } } +#define explicit 1 // { dg-warning "keyword 'explicit' defined as macro" "" { target c++26 } } +#define export 1 // { dg-warning "keyword 'export' defined as macro" "" { target c++26 } } +#define extern 1 // { dg-warning "keyword 'extern' defined as macro" "" { target c++26 } } +#define false 1 // { dg-warning "keyword 'false' defined as macro" "" { target c++26 } } +#define float 1 // { dg-warning "keyword 'float' defined as macro" "" { target c++26 } } +#define for 1 // { dg-warning "keyword 'for' defined as macro" "" { target c++26 } } +#define friend 1 // { dg-warning "keyword 'friend' defined as macro" "" { target c++26 } } +#define goto 1 // { dg-warning "keyword 'goto' defined as macro" "" { target c++26 } } +#define if 1 // { dg-warning "keyword 'if' defined as macro" "" { target c++26 } } +#define inline 1 // { dg-warning "keyword 'inline' defined as macro" "" { target c++26 } } +#define int 1 // { dg-warning "keyword 'int' defined as macro" "" { target c++26 } } +#define long 1 // { dg-warning "keyword 'long' defined as macro" "" { target c++26 } } +#define mutable 1 // { dg-warning "keyword 'mutable' defined as macro" "" { target c++26 } } +#define namespace 1 // { dg-warning "keyword 'namespace' defined as macro" "" { target c++26 } } +#define new 1 // { dg-warning "keyword 'new' defined as macro" "" { target c++26 } } +#define noexcept 1 // { dg-warning "keyword 'noexcept' defined as macro" "" { target c++26 } } +#define nullptr 1 // { dg-warning "keyword 'nullptr' defined as macro" "" { target c++26 } } +#define operator 1 // { dg-warning "keyword 'operator' defined as macro" "" { target c++26 } } +#define private 1 // { dg-warning "keyword 'private' defined as macro" "" { target c++26 } } +#define protected 1 // { dg-warning "keyword 'protected' defined as macro" "" { target c++26 } } +#define public 1 // { dg-warning "keyword 'public' defined as macro" "" { target c++26 } } +#define register 1 // { dg-warning "keyword 'register' defined as macro" "" { target c++26 } } +#define reinterpret_cast 1 // { dg-warning "keyword 'reinterpret_cast' defined as macro" "" { target c++26 } } +#define requires 1 // { dg-warning "keyword 'requires' defined as macro" "" { target c++26 } } +#define return 1 // { dg-warning "keyword 'return' defined as macro" "" { target c++26 } } +#define short 1 // { dg-warning "keyword 'short' defined as macro" "" { target c++26 } } +#define signed 1 // { dg-warning "keyword 'signed' defined as macro" "" { target c++26 } } +#define sizeof 1 // { dg-warning "keyword 'sizeof' defined as macro" "" { target c++26 } } +#define static 1 // { dg-warning "keyword 'static' defined as macro" "" { target c++26 } } +#define static_assert 1 // { dg-warning "keyword 'static_assert' defined as macro" "" { target c++26 } } +#define static_cast 1 // { dg-warning "keyword 'static_cast' defined as macro" "" { target c++26 } } +#define struct 1 // { dg-warning "keyword 'struct' defined as macro" "" { target c++26 } } +#define switch 1 // { dg-warning "keyword 'switch' defined as macro" "" { target c++26 } } +#define template 1 // { dg-warning "keyword 'template' defined as macro" "" { target c++26 } } +#define this 1 // { dg-warning "keyword 'this' defined as macro" "" { target c++26 } } +#define thread_local 1 // { dg-warning "keyword 'thread_local' defined as macro" "" { target c++26 } } +#define throw 1 // { dg-warning "keyword 'throw' defined as macro" "" { target c++26 } } +#define true 1 // { dg-warning "keyword 'true' defined as macro" "" { target c++26 } } +#define try 1 // { dg-warning "keyword 'try' defined as macro" "" { target c++26 } } +#define typedef 1 // { dg-warning "keyword 'typedef' defined as macro" "" { target c++26 } } +#define typeid 1 // { dg-warning "keyword 'typeid' defined as macro" "" { target c++26 } } +#define typename 1 // { dg-warning "keyword 'typename' defined as macro" "" { target c++26 } } +#define union 1 // { dg-warning "keyword 'union' defined as macro" "" { target c++26 } } +#define unsigned 1 // { dg-warning "keyword 'unsigned' defined as macro" "" { target c++26 } } +#define using 1 // { dg-warning "keyword 'using' defined as macro" "" { target c++26 } } +#define virtual 1 // { dg-warning "keyword 'virtual' defined as macro" "" { target c++26 } } +#define void 1 // { dg-warning "keyword 'void' defined as macro" "" { target c++26 } } +#define volatile 1 // { dg-warning "keyword 'volatile' defined as macro" "" { target c++26 } } +#define wchar_t 1 // { dg-warning "keyword 'wchar_t' defined as macro" "" { target c++26 } } +#define while 1 // { dg-warning "keyword 'while' defined as macro" "" { target c++26 } } + +// [lex.name] +#define final 1 // { dg-warning "keyword 'final' defined as macro" "" { target c++26 } } +#define import 1 // { dg-warning "keyword 'import' defined as macro" "" { target c++26 } } +#define module 1 // { dg-warning "keyword 'module' defined as macro" "" { target c++26 } } +#define override 1 // { dg-warning "keyword 'override' defined as macro" "" { target c++26 } } +#define post 1 +#define pre 1 +#define replaceable_if_eligible 1 // { dg-warning "keyword 'replaceable_if_eligible' defined as macro" "" { target c++26 } } +#define trivially_relocatable_if_eligible 1 // { dg-warning "keyword 'trivially_relocatable_if_eligible' defined as macro" "" { target c++26 } } + +// [dcl.attr] +#define assume 1 // { dg-warning "keyword 'assume' defined as macro" "" { target c++26 } } +#define carries_dependency 1 +#define deprecated 1 // { dg-warning "keyword 'deprecated' defined as macro" "" { target c++26 } } +#define fallthrough 1 // { dg-warning "keyword 'fallthrough' defined as macro" "" { target c++26 } } +#define indeterminate 1 +#define likely 1 // { dg-warning "keyword 'likely' defined as macro" "" { target c++26 } } +#define maybe_unused 1 // { dg-warning "keyword 'maybe_unused' defined as macro" "" { target c++26 } } +#define nodiscard 1 // { dg-warning "keyword 'nodiscard' defined as macro" "" { target c++26 } } +#define noreturn 1 // { dg-warning "keyword 'noreturn' defined as macro" "" { target c++26 } } +#define no_unique_address 1 // { dg-warning "keyword 'no_unique_address' defined as macro" "" { target c++26 } } +#define unlikely 1 // { dg-warning "keyword 'unlikely' defined as macro" "" { target c++26 } } diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-3.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-3.C new file mode 100644 index 0000000..8576b64 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-3.C @@ -0,0 +1,7 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "" } +// { dg-additional-options "-fmodules" { target c++20 } } + +#include "Wkeyword-macro-1.C" diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-4.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-4.C new file mode 100644 index 0000000..9ff974d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-4.C @@ -0,0 +1,112 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } +// { dg-additional-options "-fmodules" { target c++20 } } + +// [lex.key] +#undef alignas // { dg-error "undefining keyword 'alignas'" "" { target c++26 } } +#undef alignof // { dg-error "undefining keyword 'alignof'" "" { target c++26 } } +#undef asm // { dg-error "undefining keyword 'asm'" "" { target c++26 } } +#undef auto // { dg-error "undefining keyword 'auto'" "" { target c++26 } } +#undef bool // { dg-error "undefining keyword 'bool'" "" { target c++26 } } +#undef break // { dg-error "undefining keyword 'break'" "" { target c++26 } } +#undef case // { dg-error "undefining keyword 'case'" "" { target c++26 } } +#undef catch // { dg-error "undefining keyword 'catch'" "" { target c++26 } } +#undef char // { dg-error "undefining keyword 'char'" "" { target c++26 } } +#undef char16_t // { dg-error "undefining keyword 'char16_t'" "" { target c++26 } } +#undef char32_t // { dg-error "undefining keyword 'char32_t'" "" { target c++26 } } +#undef char8_t // { dg-error "undefining keyword 'char8_t'" "" { target c++26 } } +#undef class // { dg-error "undefining keyword 'class'" "" { target c++26 } } +#undef co_await // { dg-error "undefining keyword 'co_await'" "" { target c++26 } } +#undef concept // { dg-error "undefining keyword 'concept'" "" { target c++26 } } +#undef const // { dg-error "undefining keyword 'const'" "" { target c++26 } } +#undef const_cast // { dg-error "undefining keyword 'const_cast'" "" { target c++26 } } +#undef consteval // { dg-error "undefining keyword 'consteval'" "" { target c++26 } } +#undef constexpr // { dg-error "undefining keyword 'constexpr'" "" { target c++26 } } +#undef constinit // { dg-error "undefining keyword 'constinit'" "" { target c++26 } } +#undef continue // { dg-error "undefining keyword 'continue'" "" { target c++26 } } +#undef contract_assert +#undef co_return // { dg-error "undefining keyword 'co_return'" "" { target c++26 } } +#undef co_yield // { dg-error "undefining keyword 'co_yield'" "" { target c++26 } } +#undef decltype // { dg-error "undefining keyword 'decltype'" "" { target c++26 } } +#undef default // { dg-error "undefining keyword 'default'" "" { target c++26 } } +#undef delete // { dg-error "undefining keyword 'delete'" "" { target c++26 } } +#undef do // { dg-error "undefining keyword 'do'" "" { target c++26 } } +#undef double // { dg-error "undefining keyword 'double'" "" { target c++26 } } +#undef dynamic_cast // { dg-error "undefining keyword 'dynamic_cast'" "" { target c++26 } } +#undef else // { dg-error "undefining keyword 'else'" "" { target c++26 } } +#undef enum // { dg-error "undefining keyword 'enum'" "" { target c++26 } } +#undef explicit // { dg-error "undefining keyword 'explicit'" "" { target c++26 } } +#undef export // { dg-error "undefining keyword 'export'" "" { target c++26 } } +#undef extern // { dg-error "undefining keyword 'extern'" "" { target c++26 } } +#undef false // { dg-error "undefining keyword 'false'" "" { target c++26 } } +#undef float // { dg-error "undefining keyword 'float'" "" { target c++26 } } +#undef for // { dg-error "undefining keyword 'for'" "" { target c++26 } } +#undef friend // { dg-error "undefining keyword 'friend'" "" { target c++26 } } +#undef goto // { dg-error "undefining keyword 'goto'" "" { target c++26 } } +#undef if // { dg-error "undefining keyword 'if'" "" { target c++26 } } +#undef inline // { dg-error "undefining keyword 'inline'" "" { target c++26 } } +#undef int // { dg-error "undefining keyword 'int'" "" { target c++26 } } +#undef long // { dg-error "undefining keyword 'long'" "" { target c++26 } } +#undef mutable // { dg-error "undefining keyword 'mutable'" "" { target c++26 } } +#undef namespace // { dg-error "undefining keyword 'namespace'" "" { target c++26 } } +#undef new // { dg-error "undefining keyword 'new'" "" { target c++26 } } +#undef noexcept // { dg-error "undefining keyword 'noexcept'" "" { target c++26 } } +#undef nullptr // { dg-error "undefining keyword 'nullptr'" "" { target c++26 } } +#undef operator // { dg-error "undefining keyword 'operator'" "" { target c++26 } } +#undef private // { dg-error "undefining keyword 'private'" "" { target c++26 } } +#undef protected // { dg-error "undefining keyword 'protected'" "" { target c++26 } } +#undef public // { dg-error "undefining keyword 'public'" "" { target c++26 } } +#undef register // { dg-error "undefining keyword 'register'" "" { target c++26 } } +#undef reinterpret_cast // { dg-error "undefining keyword 'reinterpret_cast'" "" { target c++26 } } +#undef requires // { dg-error "undefining keyword 'requires'" "" { target c++26 } } +#undef return // { dg-error "undefining keyword 'return'" "" { target c++26 } } +#undef short // { dg-error "undefining keyword 'short'" "" { target c++26 } } +#undef signed // { dg-error "undefining keyword 'signed'" "" { target c++26 } } +#undef sizeof // { dg-error "undefining keyword 'sizeof'" "" { target c++26 } } +#undef static // { dg-error "undefining keyword 'static'" "" { target c++26 } } +#undef static_assert // { dg-error "undefining keyword 'static_assert'" "" { target c++26 } } +#undef static_cast // { dg-error "undefining keyword 'static_cast'" "" { target c++26 } } +#undef struct // { dg-error "undefining keyword 'struct'" "" { target c++26 } } +#undef switch // { dg-error "undefining keyword 'switch'" "" { target c++26 } } +#undef template // { dg-error "undefining keyword 'template'" "" { target c++26 } } +#undef this // { dg-error "undefining keyword 'this'" "" { target c++26 } } +#undef thread_local // { dg-error "undefining keyword 'thread_local'" "" { target c++26 } } +#undef throw // { dg-error "undefining keyword 'throw'" "" { target c++26 } } +#undef true // { dg-error "undefining keyword 'true'" "" { target c++26 } } +#undef try // { dg-error "undefining keyword 'try'" "" { target c++26 } } +#undef typedef // { dg-error "undefining keyword 'typedef'" "" { target c++26 } } +#undef typeid // { dg-error "undefining keyword 'typeid'" "" { target c++26 } } +#undef typename // { dg-error "undefining keyword 'typename'" "" { target c++26 } } +#undef union // { dg-error "undefining keyword 'union'" "" { target c++26 } } +#undef unsigned // { dg-error "undefining keyword 'unsigned'" "" { target c++26 } } +#undef using // { dg-error "undefining keyword 'using'" "" { target c++26 } } +#undef virtual // { dg-error "undefining keyword 'virtual'" "" { target c++26 } } +#undef void // { dg-error "undefining keyword 'void'" "" { target c++26 } } +#undef volatile // { dg-error "undefining keyword 'volatile'" "" { target c++26 } } +#undef wchar_t // { dg-error "undefining keyword 'wchar_t'" "" { target c++26 } } +#undef while // { dg-error "undefining keyword 'while'" "" { target c++26 } } + +// [lex.name] +#undef final // { dg-error "undefining keyword 'final'" "" { target c++26 } } +#undef import // { dg-error "undefining keyword 'import'" "" { target c++26 } } +#undef module // { dg-error "undefining keyword 'module'" "" { target c++26 } } +#undef override // { dg-error "undefining keyword 'override'" "" { target c++26 } } +#undef post +#undef pre +#undef replaceable_if_eligible // { dg-error "undefining keyword 'replaceable_if_eligible'" "" { target c++26 } } +#undef trivially_relocatable_if_eligible // { dg-error "undefining keyword 'trivially_relocatable_if_eligible'" "" { target c++26 } } + +// [dcl.attr] +#undef assume // { dg-error "undefining keyword 'assume'" "" { target c++26 } } +#undef carries_dependency +#undef deprecated // { dg-error "undefining keyword 'deprecated'" "" { target c++26 } } +#undef fallthrough // { dg-error "undefining keyword 'fallthrough'" "" { target c++26 } } +#undef indeterminate +#undef likely // { dg-error "undefining keyword 'likely'" "" { target c++26 } } +#undef maybe_unused // { dg-error "undefining keyword 'maybe_unused'" "" { target c++26 } } +#undef nodiscard // { dg-error "undefining keyword 'nodiscard'" "" { target c++26 } } +#undef noreturn // { dg-error "undefining keyword 'noreturn'" "" { target c++26 } } +#undef no_unique_address // { dg-error "undefining keyword 'no_unique_address'" "" { target c++26 } } +#undef unlikely // { dg-error "undefining keyword 'unlikely'" "" { target c++26 } } diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-5.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-5.C new file mode 100644 index 0000000..657797b --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-5.C @@ -0,0 +1,112 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "-pedantic" } +// { dg-additional-options "-fmodules" { target c++20 } } + +// [lex.key] +#undef alignas // { dg-warning "undefining keyword 'alignas'" "" { target c++26 } } +#undef alignof // { dg-warning "undefining keyword 'alignof'" "" { target c++26 } } +#undef asm // { dg-warning "undefining keyword 'asm'" "" { target c++26 } } +#undef auto // { dg-warning "undefining keyword 'auto'" "" { target c++26 } } +#undef bool // { dg-warning "undefining keyword 'bool'" "" { target c++26 } } +#undef break // { dg-warning "undefining keyword 'break'" "" { target c++26 } } +#undef case // { dg-warning "undefining keyword 'case'" "" { target c++26 } } +#undef catch // { dg-warning "undefining keyword 'catch'" "" { target c++26 } } +#undef char // { dg-warning "undefining keyword 'char'" "" { target c++26 } } +#undef char16_t // { dg-warning "undefining keyword 'char16_t'" "" { target c++26 } } +#undef char32_t // { dg-warning "undefining keyword 'char32_t'" "" { target c++26 } } +#undef char8_t // { dg-warning "undefining keyword 'char8_t'" "" { target c++26 } } +#undef class // { dg-warning "undefining keyword 'class'" "" { target c++26 } } +#undef co_await // { dg-warning "undefining keyword 'co_await'" "" { target c++26 } } +#undef concept // { dg-warning "undefining keyword 'concept'" "" { target c++26 } } +#undef const // { dg-warning "undefining keyword 'const'" "" { target c++26 } } +#undef const_cast // { dg-warning "undefining keyword 'const_cast'" "" { target c++26 } } +#undef consteval // { dg-warning "undefining keyword 'consteval'" "" { target c++26 } } +#undef constexpr // { dg-warning "undefining keyword 'constexpr'" "" { target c++26 } } +#undef constinit // { dg-warning "undefining keyword 'constinit'" "" { target c++26 } } +#undef continue // { dg-warning "undefining keyword 'continue'" "" { target c++26 } } +#undef contract_assert +#undef co_return // { dg-warning "undefining keyword 'co_return'" "" { target c++26 } } +#undef co_yield // { dg-warning "undefining keyword 'co_yield'" "" { target c++26 } } +#undef decltype // { dg-warning "undefining keyword 'decltype'" "" { target c++26 } } +#undef default // { dg-warning "undefining keyword 'default'" "" { target c++26 } } +#undef delete // { dg-warning "undefining keyword 'delete'" "" { target c++26 } } +#undef do // { dg-warning "undefining keyword 'do'" "" { target c++26 } } +#undef double // { dg-warning "undefining keyword 'double'" "" { target c++26 } } +#undef dynamic_cast // { dg-warning "undefining keyword 'dynamic_cast'" "" { target c++26 } } +#undef else // { dg-warning "undefining keyword 'else'" "" { target c++26 } } +#undef enum // { dg-warning "undefining keyword 'enum'" "" { target c++26 } } +#undef explicit // { dg-warning "undefining keyword 'explicit'" "" { target c++26 } } +#undef export // { dg-warning "undefining keyword 'export'" "" { target c++26 } } +#undef extern // { dg-warning "undefining keyword 'extern'" "" { target c++26 } } +#undef false // { dg-warning "undefining keyword 'false'" "" { target c++26 } } +#undef float // { dg-warning "undefining keyword 'float'" "" { target c++26 } } +#undef for // { dg-warning "undefining keyword 'for'" "" { target c++26 } } +#undef friend // { dg-warning "undefining keyword 'friend'" "" { target c++26 } } +#undef goto // { dg-warning "undefining keyword 'goto'" "" { target c++26 } } +#undef if // { dg-warning "undefining keyword 'if'" "" { target c++26 } } +#undef inline // { dg-warning "undefining keyword 'inline'" "" { target c++26 } } +#undef int // { dg-warning "undefining keyword 'int'" "" { target c++26 } } +#undef long // { dg-warning "undefining keyword 'long'" "" { target c++26 } } +#undef mutable // { dg-warning "undefining keyword 'mutable'" "" { target c++26 } } +#undef namespace // { dg-warning "undefining keyword 'namespace'" "" { target c++26 } } +#undef new // { dg-warning "undefining keyword 'new'" "" { target c++26 } } +#undef noexcept // { dg-warning "undefining keyword 'noexcept'" "" { target c++26 } } +#undef nullptr // { dg-warning "undefining keyword 'nullptr'" "" { target c++26 } } +#undef operator // { dg-warning "undefining keyword 'operator'" "" { target c++26 } } +#undef private // { dg-warning "undefining keyword 'private'" "" { target c++26 } } +#undef protected // { dg-warning "undefining keyword 'protected'" "" { target c++26 } } +#undef public // { dg-warning "undefining keyword 'public'" "" { target c++26 } } +#undef register // { dg-warning "undefining keyword 'register'" "" { target c++26 } } +#undef reinterpret_cast // { dg-warning "undefining keyword 'reinterpret_cast'" "" { target c++26 } } +#undef requires // { dg-warning "undefining keyword 'requires'" "" { target c++26 } } +#undef return // { dg-warning "undefining keyword 'return'" "" { target c++26 } } +#undef short // { dg-warning "undefining keyword 'short'" "" { target c++26 } } +#undef signed // { dg-warning "undefining keyword 'signed'" "" { target c++26 } } +#undef sizeof // { dg-warning "undefining keyword 'sizeof'" "" { target c++26 } } +#undef static // { dg-warning "undefining keyword 'static'" "" { target c++26 } } +#undef static_assert // { dg-warning "undefining keyword 'static_assert'" "" { target c++26 } } +#undef static_cast // { dg-warning "undefining keyword 'static_cast'" "" { target c++26 } } +#undef struct // { dg-warning "undefining keyword 'struct'" "" { target c++26 } } +#undef switch // { dg-warning "undefining keyword 'switch'" "" { target c++26 } } +#undef template // { dg-warning "undefining keyword 'template'" "" { target c++26 } } +#undef this // { dg-warning "undefining keyword 'this'" "" { target c++26 } } +#undef thread_local // { dg-warning "undefining keyword 'thread_local'" "" { target c++26 } } +#undef throw // { dg-warning "undefining keyword 'throw'" "" { target c++26 } } +#undef true // { dg-warning "undefining keyword 'true'" "" { target c++26 } } +#undef try // { dg-warning "undefining keyword 'try'" "" { target c++26 } } +#undef typedef // { dg-warning "undefining keyword 'typedef'" "" { target c++26 } } +#undef typeid // { dg-warning "undefining keyword 'typeid'" "" { target c++26 } } +#undef typename // { dg-warning "undefining keyword 'typename'" "" { target c++26 } } +#undef union // { dg-warning "undefining keyword 'union'" "" { target c++26 } } +#undef unsigned // { dg-warning "undefining keyword 'unsigned'" "" { target c++26 } } +#undef using // { dg-warning "undefining keyword 'using'" "" { target c++26 } } +#undef virtual // { dg-warning "undefining keyword 'virtual'" "" { target c++26 } } +#undef void // { dg-warning "undefining keyword 'void'" "" { target c++26 } } +#undef volatile // { dg-warning "undefining keyword 'volatile'" "" { target c++26 } } +#undef wchar_t // { dg-warning "undefining keyword 'wchar_t'" "" { target c++26 } } +#undef while // { dg-warning "undefining keyword 'while'" "" { target c++26 } } + +// [lex.name] +#undef final // { dg-warning "undefining keyword 'final'" "" { target c++26 } } +#undef import // { dg-warning "undefining keyword 'import'" "" { target c++26 } } +#undef module // { dg-warning "undefining keyword 'module'" "" { target c++26 } } +#undef override // { dg-warning "undefining keyword 'override'" "" { target c++26 } } +#undef post +#undef pre +#undef replaceable_if_eligible // { dg-warning "undefining keyword 'replaceable_if_eligible'" "" { target c++26 } } +#undef trivially_relocatable_if_eligible // { dg-warning "undefining keyword 'trivially_relocatable_if_eligible'" "" { target c++26 } } + +// [dcl.attr] +#undef assume // { dg-warning "undefining keyword 'assume'" "" { target c++26 } } +#undef carries_dependency +#undef deprecated // { dg-warning "undefining keyword 'deprecated'" "" { target c++26 } } +#undef fallthrough // { dg-warning "undefining keyword 'fallthrough'" "" { target c++26 } } +#undef indeterminate +#undef likely // { dg-warning "undefining keyword 'likely'" "" { target c++26 } } +#undef maybe_unused // { dg-warning "undefining keyword 'maybe_unused'" "" { target c++26 } } +#undef nodiscard // { dg-warning "undefining keyword 'nodiscard'" "" { target c++26 } } +#undef noreturn // { dg-warning "undefining keyword 'noreturn'" "" { target c++26 } } +#undef no_unique_address // { dg-warning "undefining keyword 'no_unique_address'" "" { target c++26 } } +#undef unlikely // { dg-warning "undefining keyword 'unlikely'" "" { target c++26 } } diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-6.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-6.C new file mode 100644 index 0000000..881df8b --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-6.C @@ -0,0 +1,7 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "" } +// { dg-additional-options "-fmodules" { target c++20 } } + +#include "Wkeyword-macro-4.C" diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-7.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-7.C new file mode 100644 index 0000000..30a2c8d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-7.C @@ -0,0 +1,112 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "-Wkeyword-macro" } +// { dg-additional-options "-fmodules" { target c++20 } } + +// [lex.key] +#define alignas 1 // { dg-warning "keyword 'alignas' defined as macro" "" { target c++11 } } +#define alignof 1 // { dg-warning "keyword 'alignof' defined as macro" "" { target c++11 } } +#define asm 1 // { dg-warning "keyword 'asm' defined as macro" } +#define auto 1 // { dg-warning "keyword 'auto' defined as macro" } +#define bool 1 // { dg-warning "keyword 'bool' defined as macro" } +#define break 1 // { dg-warning "keyword 'break' defined as macro" } +#define case 1 // { dg-warning "keyword 'case' defined as macro" } +#define catch 1 // { dg-warning "keyword 'catch' defined as macro" } +#define char 1 // { dg-warning "keyword 'char' defined as macro" } +#define char16_t 1 // { dg-warning "keyword 'char16_t' defined as macro" "" { target c++11 } } +#define char32_t 1 // { dg-warning "keyword 'char32_t' defined as macro" "" { target c++11 } } +#define char8_t 1 // { dg-warning "keyword 'char8_t' defined as macro" "" { target c++20 } } +#define class 1 // { dg-warning "keyword 'class' defined as macro" } +#define co_await 1 // { dg-warning "keyword 'co_await' defined as macro" "" { target c++20 } } +#define concept 1 // { dg-warning "keyword 'concept' defined as macro" "" { target c++20 } } +#define const 1 // { dg-warning "keyword 'const' defined as macro" } +#define const_cast 1 // { dg-warning "keyword 'const_cast' defined as macro" } +#define consteval 1 // { dg-warning "keyword 'consteval' defined as macro" "" { target c++20 } } +#define constexpr 1 // { dg-warning "keyword 'constexpr' defined as macro" "" { target c++11 } } +#define constinit 1 // { dg-warning "keyword 'constinit' defined as macro" "" { target c++20 } } +#define continue 1 // { dg-warning "keyword 'continue' defined as macro" } +#define contract_assert 1 +#define co_return 1 // { dg-warning "keyword 'co_return' defined as macro" "" { target c++20 } } +#define co_yield 1 // { dg-warning "keyword 'co_yield' defined as macro" "" { target c++20 } } +#define decltype 1 // { dg-warning "keyword 'decltype' defined as macro" "" { target c++11 } } +#define default 1 // { dg-warning "keyword 'default' defined as macro" } +#define delete 1 // { dg-warning "keyword 'delete' defined as macro" } +#define do 1 // { dg-warning "keyword 'do' defined as macro" } +#define double 1 // { dg-warning "keyword 'double' defined as macro" } +#define dynamic_cast 1 // { dg-warning "keyword 'dynamic_cast' defined as macro" } +#define else 1 // { dg-warning "keyword 'else' defined as macro" } +#define enum 1 // { dg-warning "keyword 'enum' defined as macro" } +#define explicit 1 // { dg-warning "keyword 'explicit' defined as macro" } +#define export 1 // { dg-warning "keyword 'export' defined as macro" } +#define extern 1 // { dg-warning "keyword 'extern' defined as macro" } +#define false 1 // { dg-warning "keyword 'false' defined as macro" } +#define float 1 // { dg-warning "keyword 'float' defined as macro" } +#define for 1 // { dg-warning "keyword 'for' defined as macro" } +#define friend 1 // { dg-warning "keyword 'friend' defined as macro" } +#define goto 1 // { dg-warning "keyword 'goto' defined as macro" } +#define if 1 // { dg-warning "keyword 'if' defined as macro" } +#define inline 1 // { dg-warning "keyword 'inline' defined as macro" } +#define int 1 // { dg-warning "keyword 'int' defined as macro" } +#define long 1 // { dg-warning "keyword 'long' defined as macro" } +#define mutable 1 // { dg-warning "keyword 'mutable' defined as macro" } +#define namespace 1 // { dg-warning "keyword 'namespace' defined as macro" } +#define new 1 // { dg-warning "keyword 'new' defined as macro" } +#define noexcept 1 // { dg-warning "keyword 'noexcept' defined as macro" "" { target c++11 } } +#define nullptr 1 // { dg-warning "keyword 'nullptr' defined as macro" "" { target c++11 } } +#define operator 1 // { dg-warning "keyword 'operator' defined as macro" } +#define private 1 // { dg-warning "keyword 'private' defined as macro" } +#define protected 1 // { dg-warning "keyword 'protected' defined as macro" } +#define public 1 // { dg-warning "keyword 'public' defined as macro" } +#define register 1 // { dg-warning "keyword 'register' defined as macro" } +#define reinterpret_cast 1 // { dg-warning "keyword 'reinterpret_cast' defined as macro" } +#define requires 1 // { dg-warning "keyword 'requires' defined as macro" "" { target c++20 } } +#define return 1 // { dg-warning "keyword 'return' defined as macro" } +#define short 1 // { dg-warning "keyword 'short' defined as macro" } +#define signed 1 // { dg-warning "keyword 'signed' defined as macro" } +#define sizeof 1 // { dg-warning "keyword 'sizeof' defined as macro" } +#define static 1 // { dg-warning "keyword 'static' defined as macro" } +#define static_assert 1 // { dg-warning "keyword 'static_assert' defined as macro" "" { target c++11 } } +#define static_cast 1 // { dg-warning "keyword 'static_cast' defined as macro" } +#define struct 1 // { dg-warning "keyword 'struct' defined as macro" } +#define switch 1 // { dg-warning "keyword 'switch' defined as macro" } +#define template 1 // { dg-warning "keyword 'template' defined as macro" } +#define this 1 // { dg-warning "keyword 'this' defined as macro" } +#define thread_local 1 // { dg-warning "keyword 'thread_local' defined as macro" "" { target c++11 } } +#define throw 1 // { dg-warning "keyword 'throw' defined as macro" } +#define true 1 // { dg-warning "keyword 'true' defined as macro" } +#define try 1 // { dg-warning "keyword 'try' defined as macro" } +#define typedef 1 // { dg-warning "keyword 'typedef' defined as macro" } +#define typeid 1 // { dg-warning "keyword 'typeid' defined as macro" } +#define typename 1 // { dg-warning "keyword 'typename' defined as macro" } +#define union 1 // { dg-warning "keyword 'union' defined as macro" } +#define unsigned 1 // { dg-warning "keyword 'unsigned' defined as macro" } +#define using 1 // { dg-warning "keyword 'using' defined as macro" } +#define virtual 1 // { dg-warning "keyword 'virtual' defined as macro" } +#define void 1 // { dg-warning "keyword 'void' defined as macro" } +#define volatile 1 // { dg-warning "keyword 'volatile' defined as macro" } +#define wchar_t 1 // { dg-warning "keyword 'wchar_t' defined as macro" } +#define while 1 // { dg-warning "keyword 'while' defined as macro" } + +// [lex.name] +#define final 1 // { dg-warning "keyword 'final' defined as macro" "" { target c++11 } } +#define import 1 // { dg-warning "keyword 'import' defined as macro" "" { target c++20 } } +#define module 1 // { dg-warning "keyword 'module' defined as macro" "" { target c++20 } } +#define override 1 // { dg-warning "keyword 'override' defined as macro" "" { target c++11 } } +#define post 1 +#define pre 1 +#define replaceable_if_eligible 1 // { dg-warning "keyword 'replaceable_if_eligible' defined as macro" "" { target c++26 } } +#define trivially_relocatable_if_eligible 1 // { dg-warning "keyword 'trivially_relocatable_if_eligible' defined as macro" "" { target c++26 } } + +// [dcl.attr] +#define assume 1 // { dg-warning "keyword 'assume' defined as macro" "" { target c++23 } } +#define carries_dependency 1 // { dg-warning "keyword 'carries_dependency' defined as macro" "" { target { c++11 && c++23_down } } } +#define deprecated 1 // { dg-warning "keyword 'deprecated' defined as macro" "" { target c++14 } } +#define fallthrough 1 // { dg-warning "keyword 'fallthrough' defined as macro" "" { target c++17 } } +#define indeterminate 1 +#define likely 1 // { dg-warning "keyword 'likely' defined as macro" "" { target c++20 } } +#define maybe_unused 1 // { dg-warning "keyword 'maybe_unused' defined as macro" "" { target c++17 } } +#define nodiscard 1 // { dg-warning "keyword 'nodiscard' defined as macro" "" { target c++17 } } +#define noreturn 1 // { dg-warning "keyword 'noreturn' defined as macro" "" { target c++11 } } +#define no_unique_address 1 // { dg-warning "keyword 'no_unique_address' defined as macro" "" { target c++20 } } +#define unlikely 1 // { dg-warning "keyword 'unlikely' defined as macro" "" { target c++20 } } diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-8.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-8.C new file mode 100644 index 0000000..7dcc377 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-8.C @@ -0,0 +1,112 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "-Wkeyword-macro" } +// { dg-additional-options "-fmodules" { target c++20 } } + +// [lex.key] +#undef alignas // { dg-warning "undefining keyword 'alignas'" "" { target c++11 } } +#undef alignof // { dg-warning "undefining keyword 'alignof'" "" { target c++11 } } +#undef asm // { dg-warning "undefining keyword 'asm'" } +#undef auto // { dg-warning "undefining keyword 'auto'" } +#undef bool // { dg-warning "undefining keyword 'bool'" } +#undef break // { dg-warning "undefining keyword 'break'" } +#undef case // { dg-warning "undefining keyword 'case'" } +#undef catch // { dg-warning "undefining keyword 'catch'" } +#undef char // { dg-warning "undefining keyword 'char'" } +#undef char16_t // { dg-warning "undefining keyword 'char16_t'" "" { target c++11 } } +#undef char32_t // { dg-warning "undefining keyword 'char32_t'" "" { target c++11 } } +#undef char8_t // { dg-warning "undefining keyword 'char8_t'" "" { target c++20 } } +#undef class // { dg-warning "undefining keyword 'class'" } +#undef co_await // { dg-warning "undefining keyword 'co_await'" "" { target c++20 } } +#undef concept // { dg-warning "undefining keyword 'concept'" "" { target c++20 } } +#undef const // { dg-warning "undefining keyword 'const'" } +#undef const_cast // { dg-warning "undefining keyword 'const_cast'" } +#undef consteval // { dg-warning "undefining keyword 'consteval'" "" { target c++20 } } +#undef constexpr // { dg-warning "undefining keyword 'constexpr'" "" { target c++11 } } +#undef constinit // { dg-warning "undefining keyword 'constinit'" "" { target c++20 } } +#undef continue // { dg-warning "undefining keyword 'continue'" } +#undef contract_assert +#undef co_return // { dg-warning "undefining keyword 'co_return'" "" { target c++20 } } +#undef co_yield // { dg-warning "undefining keyword 'co_yield'" "" { target c++20 } } +#undef decltype // { dg-warning "undefining keyword 'decltype'" "" { target c++11 } } +#undef default // { dg-warning "undefining keyword 'default'" } +#undef delete // { dg-warning "undefining keyword 'delete'" } +#undef do // { dg-warning "undefining keyword 'do'" } +#undef double // { dg-warning "undefining keyword 'double'" } +#undef dynamic_cast // { dg-warning "undefining keyword 'dynamic_cast'" } +#undef else // { dg-warning "undefining keyword 'else'" } +#undef enum // { dg-warning "undefining keyword 'enum'" } +#undef explicit // { dg-warning "undefining keyword 'explicit'" } +#undef export // { dg-warning "undefining keyword 'export'" } +#undef extern // { dg-warning "undefining keyword 'extern'" } +#undef false // { dg-warning "undefining keyword 'false'" } +#undef float // { dg-warning "undefining keyword 'float'" } +#undef for // { dg-warning "undefining keyword 'for'" } +#undef friend // { dg-warning "undefining keyword 'friend'" } +#undef goto // { dg-warning "undefining keyword 'goto'" } +#undef if // { dg-warning "undefining keyword 'if'" } +#undef inline // { dg-warning "undefining keyword 'inline'" } +#undef int // { dg-warning "undefining keyword 'int'" } +#undef long // { dg-warning "undefining keyword 'long'" } +#undef mutable // { dg-warning "undefining keyword 'mutable'" } +#undef namespace // { dg-warning "undefining keyword 'namespace'" } +#undef new // { dg-warning "undefining keyword 'new'" } +#undef noexcept // { dg-warning "undefining keyword 'noexcept'" "" { target c++11 } } +#undef nullptr // { dg-warning "undefining keyword 'nullptr'" "" { target c++11 } } +#undef operator // { dg-warning "undefining keyword 'operator'" } +#undef private // { dg-warning "undefining keyword 'private'" } +#undef protected // { dg-warning "undefining keyword 'protected'" } +#undef public // { dg-warning "undefining keyword 'public'" } +#undef register // { dg-warning "undefining keyword 'register'" } +#undef reinterpret_cast // { dg-warning "undefining keyword 'reinterpret_cast'" } +#undef requires // { dg-warning "undefining keyword 'requires'" "" { target c++20 } } +#undef return // { dg-warning "undefining keyword 'return'" } +#undef short // { dg-warning "undefining keyword 'short'" } +#undef signed // { dg-warning "undefining keyword 'signed'" } +#undef sizeof // { dg-warning "undefining keyword 'sizeof'" } +#undef static // { dg-warning "undefining keyword 'static'" } +#undef static_assert // { dg-warning "undefining keyword 'static_assert'" "" { target c++11 } } +#undef static_cast // { dg-warning "undefining keyword 'static_cast'" } +#undef struct // { dg-warning "undefining keyword 'struct'" } +#undef switch // { dg-warning "undefining keyword 'switch'" } +#undef template // { dg-warning "undefining keyword 'template'" } +#undef this // { dg-warning "undefining keyword 'this'" } +#undef thread_local // { dg-warning "undefining keyword 'thread_local'" "" { target c++11 } } +#undef throw // { dg-warning "undefining keyword 'throw'" } +#undef true // { dg-warning "undefining keyword 'true'" } +#undef try // { dg-warning "undefining keyword 'try'" } +#undef typedef // { dg-warning "undefining keyword 'typedef'" } +#undef typeid // { dg-warning "undefining keyword 'typeid'" } +#undef typename // { dg-warning "undefining keyword 'typename'" } +#undef union // { dg-warning "undefining keyword 'union'" } +#undef unsigned // { dg-warning "undefining keyword 'unsigned'" } +#undef using // { dg-warning "undefining keyword 'using'" } +#undef virtual // { dg-warning "undefining keyword 'virtual'" } +#undef void // { dg-warning "undefining keyword 'void'" } +#undef volatile // { dg-warning "undefining keyword 'volatile'" } +#undef wchar_t // { dg-warning "undefining keyword 'wchar_t'" } +#undef while // { dg-warning "undefining keyword 'while'" } + +// [lex.name] +#undef final // { dg-warning "undefining keyword 'final'" "" { target c++11 } } +#undef import // { dg-warning "undefining keyword 'import'" "" { target c++20 } } +#undef module // { dg-warning "undefining keyword 'module'" "" { target c++20 } } +#undef override // { dg-warning "undefining keyword 'override'" "" { target c++11 } } +#undef post +#undef pre +#undef replaceable_if_eligible // { dg-warning "undefining keyword 'replaceable_if_eligible'" "" { target c++26 } } +#undef trivially_relocatable_if_eligible // { dg-warning "undefining keyword 'trivially_relocatable_if_eligible'" "" { target c++26 } } + +// [dcl.attr] +#undef assume // { dg-warning "undefining keyword 'assume'" "" { target c++23 } } +#undef carries_dependency // { dg-warning "undefining keyword 'carries_dependency'" "" { target { c++11 && c++23_down } } } +#undef deprecated // { dg-warning "undefining keyword 'deprecated'" "" { target c++14 } } +#undef fallthrough // { dg-warning "undefining keyword 'fallthrough'" "" { target c++17 } } +#undef indeterminate +#undef likely // { dg-warning "undefining keyword 'likely'" "" { target c++20 } } +#undef maybe_unused // { dg-warning "undefining keyword 'maybe_unused'" "" { target c++17 } } +#undef nodiscard // { dg-warning "undefining keyword 'nodiscard'" "" { target c++17 } } +#undef noreturn // { dg-warning "undefining keyword 'noreturn'" "" { target c++11 } } +#undef no_unique_address // { dg-warning "undefining keyword 'no_unique_address'" "" { target c++20 } } +#undef unlikely // { dg-warning "undefining keyword 'unlikely'" "" { target c++20 } } diff --git a/gcc/testsuite/g++.dg/warn/Wkeyword-macro-9.C b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-9.C new file mode 100644 index 0000000..741cdee --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wkeyword-macro-9.C @@ -0,0 +1,22 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// [cpp.replace.general]/9 +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } + +#undef for // { dg-error "undefining keyword 'for'" "" { target c++26 } } +#define for for // { dg-error "keyword 'for' defined as macro" "" { target c++26 } } +#undef for // { dg-error "undefining keyword 'for'" "" { target c++26 } } +#define while do // { dg-error "keyword 'while' defined as macro" "" { target c++26 } } +#define while do // { dg-error "keyword 'while' defined as macro" "" { target c++26 } } +#define while for // { dg-error "keyword 'while' defined as macro" "" { target c++26 } } + // { dg-error "'while' redefined" "" { target *-*-* } .-1 } +#undef while // { dg-error "undefining keyword 'while'" "" { target c++26 } } +#define while while // { dg-error "keyword 'while' defined as macro" "" { target c++26 } } +#define private public // { dg-error "keyword 'private' defined as macro" "" { target c++26 } } +#define inline // { dg-error "keyword 'inline' defined as macro" "" { target c++26 } } +#undef inline // { dg-error "undefining keyword 'inline'" "" { target c++26 } } +#define inline __inline__ __attribute__((__always_inline__)) // { dg-error "keyword 'inline' defined as macro" "" { target c++26 } } +#define likely(a) a +#undef likely // { dg-error "undefining keyword 'likely'" "" { target c++26 } } +#define unlikely(a, b, c) a + b + c +#define unlikely(a, b, c) a + b + c diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-1.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-1.c new file mode 100644 index 0000000..0b2d78f --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-1.c @@ -0,0 +1,62 @@ +// { dg-do preprocess } +// { dg-options "-Wkeyword-macro -std=c23" } + +#define _Alignas 1 // { dg-warning "keyword '_Alignas' defined as macro" } +#define _Alignof 1 // { dg-warning "keyword '_Alignof' defined as macro" } +#define _Atomic 1 // { dg-warning "keyword '_Atomic' defined as macro" } +#define _BitInt 1 // { dg-warning "keyword '_BitInt' defined as macro" } +#define _Bool 1 // { dg-warning "keyword '_Bool' defined as macro" } +#define _Complex 1 // { dg-warning "keyword '_Complex' defined as macro" } +#define _Decimal128 1 // { dg-warning "keyword '_Decimal128' defined as macro" } +#define _Decimal32 1 // { dg-warning "keyword '_Decimal32' defined as macro" } +#define _Decimal64 1 // { dg-warning "keyword '_Decimal64' defined as macro" } +#define _Generic 1 // { dg-warning "keyword '_Generic' defined as macro" } +#define _Imaginary 1 // { dg-warning "keyword '_Imaginary' defined as macro" } +#define _Noreturn 1 // { dg-warning "keyword '_Noreturn' defined as macro" } +#define _Static_assert 1 // { dg-warning "keyword '_Static_assert' defined as macro" } +#define _Thread_local 1 // { dg-warning "keyword '_Thread_local' defined as macro" } +#define alignas 1 // { dg-warning "keyword 'alignas' defined as macro" } +#define alignof 1 // { dg-warning "keyword 'alignof' defined as macro" } +#define auto 1 // { dg-warning "keyword 'auto' defined as macro" } +#define bool 1 // { dg-warning "keyword 'bool' defined as macro" } +#define break 1 // { dg-warning "keyword 'break' defined as macro" } +#define case 1 // { dg-warning "keyword 'case' defined as macro" } +#define char 1 // { dg-warning "keyword 'char' defined as macro" } +#define const 1 // { dg-warning "keyword 'const' defined as macro" } +#define constexpr 1 // { dg-warning "keyword 'constexpr' defined as macro" } +#define continue 1 // { dg-warning "keyword 'continue' defined as macro" } +#define default 1 // { dg-warning "keyword 'default' defined as macro" } +#define do 1 // { dg-warning "keyword 'do' defined as macro" } +#define double 1 // { dg-warning "keyword 'double' defined as macro" } +#define else 1 // { dg-warning "keyword 'else' defined as macro" } +#define enum 1 // { dg-warning "keyword 'enum' defined as macro" } +#define extern 1 // { dg-warning "keyword 'extern' defined as macro" } +#define false 1 // { dg-warning "keyword 'false' defined as macro" } +#define float 1 // { dg-warning "keyword 'float' defined as macro" } +#define for 1 // { dg-warning "keyword 'for' defined as macro" } +#define goto 1 // { dg-warning "keyword 'goto' defined as macro" } +#define if 1 // { dg-warning "keyword 'if' defined as macro" } +#define inline 1 // { dg-warning "keyword 'inline' defined as macro" } +#define int 1 // { dg-warning "keyword 'int' defined as macro" } +#define long 1 // { dg-warning "keyword 'long' defined as macro" } +#define nullptr 1 // { dg-warning "keyword 'nullptr' defined as macro" } +#define register 1 // { dg-warning "keyword 'register' defined as macro" } +#define restrict 1 // { dg-warning "keyword 'restrict' defined as macro" } +#define return 1 // { dg-warning "keyword 'return' defined as macro" } +#define short 1 // { dg-warning "keyword 'short' defined as macro" } +#define signed 1 // { dg-warning "keyword 'signed' defined as macro" } +#define sizeof 1 // { dg-warning "keyword 'sizeof' defined as macro" } +#define static 1 // { dg-warning "keyword 'static' defined as macro" } +#define static_assert 1 // { dg-warning "keyword 'static_assert' defined as macro" } +#define struct 1 // { dg-warning "keyword 'struct' defined as macro" } +#define switch 1 // { dg-warning "keyword 'switch' defined as macro" } +#define thread_local 1 // { dg-warning "keyword 'thread_local' defined as macro" } +#define true 1 // { dg-warning "keyword 'true' defined as macro" } +#define typedef 1 // { dg-warning "keyword 'typedef' defined as macro" } +#define typeof 1 // { dg-warning "keyword 'typeof' defined as macro" } +#define typeof_unqual 1 // { dg-warning "keyword 'typeof_unqual' defined as macro" } +#define union 1 // { dg-warning "keyword 'union' defined as macro" } +#define unsigned 1 // { dg-warning "keyword 'unsigned' defined as macro" } +#define void 1 // { dg-warning "keyword 'void' defined as macro" } +#define volatile 1 // { dg-warning "keyword 'volatile' defined as macro" } +#define while 1 // { dg-warning "keyword 'while' defined as macro" } diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-2.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-2.c new file mode 100644 index 0000000..329a55a --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-2.c @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=c23" } + +#include "Wkeyword-macro-1.c" diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-3.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-3.c new file mode 100644 index 0000000..f631b8e --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-3.c @@ -0,0 +1,62 @@ +// { dg-do preprocess } +// { dg-options "-Wkeyword-macro -std=c23" } + +#undef _Alignas // { dg-warning "undefining keyword '_Alignas'" } +#undef _Alignof // { dg-warning "undefining keyword '_Alignof'" } +#undef _Atomic // { dg-warning "undefining keyword '_Atomic'" } +#undef _BitInt // { dg-warning "undefining keyword '_BitInt'" } +#undef _Bool // { dg-warning "undefining keyword '_Bool'" } +#undef _Complex // { dg-warning "undefining keyword '_Complex'" } +#undef _Decimal128 // { dg-warning "undefining keyword '_Decimal128'" } +#undef _Decimal32 // { dg-warning "undefining keyword '_Decimal32'" } +#undef _Decimal64 // { dg-warning "undefining keyword '_Decimal64'" } +#undef _Generic // { dg-warning "undefining keyword '_Generic'" } +#undef _Imaginary // { dg-warning "undefining keyword '_Imaginary'" } +#undef _Noreturn // { dg-warning "undefining keyword '_Noreturn'" } +#undef _Static_assert // { dg-warning "undefining keyword '_Static_assert'" } +#undef _Thread_local // { dg-warning "undefining keyword '_Thread_local'" } +#undef alignas // { dg-warning "undefining keyword 'alignas'" } +#undef alignof // { dg-warning "undefining keyword 'alignof'" } +#undef auto // { dg-warning "undefining keyword 'auto'" } +#undef bool // { dg-warning "undefining keyword 'bool'" } +#undef break // { dg-warning "undefining keyword 'break'" } +#undef case // { dg-warning "undefining keyword 'case'" } +#undef char // { dg-warning "undefining keyword 'char'" } +#undef const // { dg-warning "undefining keyword 'const'" } +#undef constexpr // { dg-warning "undefining keyword 'constexpr'" } +#undef continue // { dg-warning "undefining keyword 'continue'" } +#undef default // { dg-warning "undefining keyword 'default'" } +#undef do // { dg-warning "undefining keyword 'do'" } +#undef double // { dg-warning "undefining keyword 'double'" } +#undef else // { dg-warning "undefining keyword 'else'" } +#undef enum // { dg-warning "undefining keyword 'enum'" } +#undef extern // { dg-warning "undefining keyword 'extern'" } +#undef false // { dg-warning "undefining keyword 'false'" } +#undef float // { dg-warning "undefining keyword 'float'" } +#undef for // { dg-warning "undefining keyword 'for'" } +#undef goto // { dg-warning "undefining keyword 'goto'" } +#undef if // { dg-warning "undefining keyword 'if'" } +#undef inline // { dg-warning "undefining keyword 'inline'" } +#undef int // { dg-warning "undefining keyword 'int'" } +#undef long // { dg-warning "undefining keyword 'long'" } +#undef nullptr // { dg-warning "undefining keyword 'nullptr'" } +#undef register // { dg-warning "undefining keyword 'register'" } +#undef restrict // { dg-warning "undefining keyword 'restrict'" } +#undef return // { dg-warning "undefining keyword 'return'" } +#undef short // { dg-warning "undefining keyword 'short'" } +#undef signed // { dg-warning "undefining keyword 'signed'" } +#undef sizeof // { dg-warning "undefining keyword 'sizeof'" } +#undef static // { dg-warning "undefining keyword 'static'" } +#undef static_assert // { dg-warning "undefining keyword 'static_assert'" } +#undef struct // { dg-warning "undefining keyword 'struct'" } +#undef switch // { dg-warning "undefining keyword 'switch'" } +#undef thread_local // { dg-warning "undefining keyword 'thread_local'" } +#undef true // { dg-warning "undefining keyword 'true'" } +#undef typedef // { dg-warning "undefining keyword 'typedef'" } +#undef typeof // { dg-warning "undefining keyword 'typeof'" } +#undef typeof_unqual // { dg-warning "undefining keyword 'typeof_unqual'" } +#undef union // { dg-warning "undefining keyword 'union'" } +#undef unsigned // { dg-warning "undefining keyword 'unsigned'" } +#undef void // { dg-warning "undefining keyword 'void'" } +#undef volatile // { dg-warning "undefining keyword 'volatile'" } +#undef while // { dg-warning "undefining keyword 'while'" } diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-4.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-4.c new file mode 100644 index 0000000..796d654 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-4.c @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=c23" } + +#include "Wkeyword-macro-3.c" diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-5.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-5.c new file mode 100644 index 0000000..c61a1ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-5.c @@ -0,0 +1,47 @@ +// { dg-do preprocess } +// { dg-options "-Wkeyword-macro -std=c17" } + +#define _Alignas 1 // { dg-warning "keyword '_Alignas' defined as macro" } +#define _Alignof 1 // { dg-warning "keyword '_Alignof' defined as macro" } +#define _Atomic 1 // { dg-warning "keyword '_Atomic' defined as macro" } +#define _Bool 1 // { dg-warning "keyword '_Bool' defined as macro" } +#define _Complex 1 // { dg-warning "keyword '_Complex' defined as macro" } +#define _Generic 1 // { dg-warning "keyword '_Generic' defined as macro" } +#define _Imaginary 1 // { dg-warning "keyword '_Imaginary' defined as macro" } +#define _Noreturn 1 // { dg-warning "keyword '_Noreturn' defined as macro" } +#define _Static_assert 1 // { dg-warning "keyword '_Static_assert' defined as macro" } +#define _Thread_local 1 // { dg-warning "keyword '_Thread_local' defined as macro" } +#define auto 1 // { dg-warning "keyword 'auto' defined as macro" } +#define break 1 // { dg-warning "keyword 'break' defined as macro" } +#define case 1 // { dg-warning "keyword 'case' defined as macro" } +#define char 1 // { dg-warning "keyword 'char' defined as macro" } +#define const 1 // { dg-warning "keyword 'const' defined as macro" } +#define continue 1 // { dg-warning "keyword 'continue' defined as macro" } +#define default 1 // { dg-warning "keyword 'default' defined as macro" } +#define do 1 // { dg-warning "keyword 'do' defined as macro" } +#define double 1 // { dg-warning "keyword 'double' defined as macro" } +#define else 1 // { dg-warning "keyword 'else' defined as macro" } +#define enum 1 // { dg-warning "keyword 'enum' defined as macro" } +#define extern 1 // { dg-warning "keyword 'extern' defined as macro" } +#define float 1 // { dg-warning "keyword 'float' defined as macro" } +#define for 1 // { dg-warning "keyword 'for' defined as macro" } +#define goto 1 // { dg-warning "keyword 'goto' defined as macro" } +#define if 1 // { dg-warning "keyword 'if' defined as macro" } +#define inline 1 // { dg-warning "keyword 'inline' defined as macro" } +#define int 1 // { dg-warning "keyword 'int' defined as macro" } +#define long 1 // { dg-warning "keyword 'long' defined as macro" } +#define register 1 // { dg-warning "keyword 'register' defined as macro" } +#define restrict 1 // { dg-warning "keyword 'restrict' defined as macro" } +#define return 1 // { dg-warning "keyword 'return' defined as macro" } +#define short 1 // { dg-warning "keyword 'short' defined as macro" } +#define signed 1 // { dg-warning "keyword 'signed' defined as macro" } +#define sizeof 1 // { dg-warning "keyword 'sizeof' defined as macro" } +#define static 1 // { dg-warning "keyword 'static' defined as macro" } +#define struct 1 // { dg-warning "keyword 'struct' defined as macro" } +#define switch 1 // { dg-warning "keyword 'switch' defined as macro" } +#define typedef 1 // { dg-warning "keyword 'typedef' defined as macro" } +#define union 1 // { dg-warning "keyword 'union' defined as macro" } +#define unsigned 1 // { dg-warning "keyword 'unsigned' defined as macro" } +#define void 1 // { dg-warning "keyword 'void' defined as macro" } +#define volatile 1 // { dg-warning "keyword 'volatile' defined as macro" } +#define while 1 // { dg-warning "keyword 'while' defined as macro" } diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-6.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-6.c new file mode 100644 index 0000000..760ece6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-6.c @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=c17" } + +#include "Wkeyword-macro-5.c" diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-7.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-7.c new file mode 100644 index 0000000..dc146d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-7.c @@ -0,0 +1,47 @@ +// { dg-do preprocess } +// { dg-options "-Wkeyword-macro -std=c17" } + +#undef _Alignas // { dg-warning "undefining keyword '_Alignas'" } +#undef _Alignof // { dg-warning "undefining keyword '_Alignof'" } +#undef _Atomic // { dg-warning "undefining keyword '_Atomic'" } +#undef _Bool // { dg-warning "undefining keyword '_Bool'" } +#undef _Complex // { dg-warning "undefining keyword '_Complex'" } +#undef _Generic // { dg-warning "undefining keyword '_Generic'" } +#undef _Imaginary // { dg-warning "undefining keyword '_Imaginary'" } +#undef _Noreturn // { dg-warning "undefining keyword '_Noreturn'" } +#undef _Static_assert // { dg-warning "undefining keyword '_Static_assert'" } +#undef _Thread_local // { dg-warning "undefining keyword '_Thread_local'" } +#undef auto // { dg-warning "undefining keyword 'auto'" } +#undef break // { dg-warning "undefining keyword 'break'" } +#undef case // { dg-warning "undefining keyword 'case'" } +#undef char // { dg-warning "undefining keyword 'char'" } +#undef const // { dg-warning "undefining keyword 'const'" } +#undef continue // { dg-warning "undefining keyword 'continue'" } +#undef default // { dg-warning "undefining keyword 'default'" } +#undef do // { dg-warning "undefining keyword 'do'" } +#undef double // { dg-warning "undefining keyword 'double'" } +#undef else // { dg-warning "undefining keyword 'else'" } +#undef enum // { dg-warning "undefining keyword 'enum'" } +#undef extern // { dg-warning "undefining keyword 'extern'" } +#undef float // { dg-warning "undefining keyword 'float'" } +#undef for // { dg-warning "undefining keyword 'for'" } +#undef goto // { dg-warning "undefining keyword 'goto'" } +#undef if // { dg-warning "undefining keyword 'if'" } +#undef inline // { dg-warning "undefining keyword 'inline'" } +#undef int // { dg-warning "undefining keyword 'int'" } +#undef long // { dg-warning "undefining keyword 'long'" } +#undef register // { dg-warning "undefining keyword 'register'" } +#undef restrict // { dg-warning "undefining keyword 'restrict'" } +#undef return // { dg-warning "undefining keyword 'return'" } +#undef short // { dg-warning "undefining keyword 'short'" } +#undef signed // { dg-warning "undefining keyword 'signed'" } +#undef sizeof // { dg-warning "undefining keyword 'sizeof'" } +#undef static // { dg-warning "undefining keyword 'static'" } +#undef struct // { dg-warning "undefining keyword 'struct'" } +#undef switch // { dg-warning "undefining keyword 'switch'" } +#undef typedef // { dg-warning "undefining keyword 'typedef'" } +#undef union // { dg-warning "undefining keyword 'union'" } +#undef unsigned // { dg-warning "undefining keyword 'unsigned'" } +#undef void // { dg-warning "undefining keyword 'void'" } +#undef volatile // { dg-warning "undefining keyword 'volatile'" } +#undef while // { dg-warning "undefining keyword 'while'" } diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-8.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-8.c new file mode 100644 index 0000000..b209f40 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-8.c @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=c17" } + +#include "Wkeyword-macro-7.c" diff --git a/gcc/testsuite/gcc.dg/Wkeyword-macro-9.c b/gcc/testsuite/gcc.dg/Wkeyword-macro-9.c new file mode 100644 index 0000000..5d6b650 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wkeyword-macro-9.c @@ -0,0 +1,15 @@ +// { dg-do preprocess } +// { dg-options "-Wkeyword-macro" } + +#undef for // { dg-warning "undefining keyword 'for'" } +#define for for // { dg-warning "keyword 'for' defined as macro" } +#undef for // { dg-warning "undefining keyword 'for'" } +#define while do // { dg-warning "keyword 'while' defined as macro" } +#define while do // { dg-warning "keyword 'while' defined as macro" } +#define while for // { dg-warning "keyword 'while' defined as macro" } + // { dg-warning "'while' redefined" "" { target *-*-* } .-1 } +#undef while // { dg-warning "undefining keyword 'while'" } +#define while while // { dg-warning "keyword 'while' defined as macro" } +#define inline // { dg-warning "keyword 'inline' defined as macro" } +#undef inline // { dg-warning "undefining keyword 'inline'" } +#define inline __inline__ __attribute__((__always_inline__)) // { dg-warning "keyword 'inline' defined as macro" } diff --git a/gcc/testsuite/gcc.dg/torture/hardbool-ai.c b/gcc/testsuite/gcc.dg/torture/hardbool-ai.c new file mode 100644 index 0000000..97569a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/hardbool-ai.c @@ -0,0 +1,7 @@ +/* { dg-do run } */ + +#define basetype _Atomic int + +#define NO_BITFIELDS 1 + +#include "hardbool.c" diff --git a/gcc/testsuite/gcc.dg/torture/hardbool-vi.c b/gcc/testsuite/gcc.dg/torture/hardbool-vi.c new file mode 100644 index 0000000..898d395 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/hardbool-vi.c @@ -0,0 +1,5 @@ +/* { dg-do run } */ + +#define basetype volatile int + +#include "hardbool.c" diff --git a/gcc/testsuite/gcc.dg/torture/hardbool.c b/gcc/testsuite/gcc.dg/torture/hardbool.c index 0168495..ed0c598 100644 --- a/gcc/testsuite/gcc.dg/torture/hardbool.c +++ b/gcc/testsuite/gcc.dg/torture/hardbool.c @@ -21,8 +21,12 @@ typedef unsigned char __attribute__ ((__hardbool__ (1, 0))) zbool; struct hs { hbool a[2]; +#ifndef NO_BITFIELDS hbool x:2; hbool y:5; +#else + hbool x, y; +#endif zbool z:1; }; @@ -57,6 +61,30 @@ int ghs(hbool s) { int t = (hbool)2; +hbool add1(hbool *s) { + return *s += 1; +} + +hbool preinc(hbool *s) { + return ++*s; +} + +hbool postinc(hbool *s) { + return (*s)++; +} + +hbool sub1(hbool *s) { + return *s -= 1; +} + +hbool predec(hbool *s) { + return --*s; +} + +hbool postdec(hbool *s) { + return (*s)--; +} + void check_pfalse (hbool *p) { assert (!*p); @@ -114,5 +142,43 @@ int main () { check_vtrue (h2 (2)); check_vtrue (h2 (1)); check_vfalse (h2 (0)); -} + hbool v; + v = 0; + check_vtrue (add1 (&v)); + assert (v); + v = 0; + check_vtrue (preinc (&v)); + assert (v); + v = 0; + check_vfalse (postinc (&v)); + assert (v); + v = 0; + check_vtrue (sub1 (&v)); + assert (v); + v = 0; + check_vtrue (predec (&v)); + assert (v); + v = 0; + check_vfalse (postdec (&v)); + assert (v); + + v = 1; + check_vtrue (add1 (&v)); + assert (v); + v = 1; + check_vtrue (preinc (&v)); + assert (v); + v = 1; + check_vtrue (postinc (&v)); + assert (v); + v = 1; + check_vfalse (sub1 (&v)); + assert (!v); + v = 1; + check_vfalse (predec (&v)); + assert (!v); + v = 1; + check_vtrue (postdec (&v)); + assert (!v); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c new file mode 100644 index 0000000..f80baf3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-107.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +struct vec_char_16 +{ + unsigned char raw[2]; +}; + +static inline struct vec_char_16 +Dup128VecFromValues(unsigned char t0, unsigned char t1) +{ + struct vec_char_16 result; + result.raw[0] = t0; + result.raw[1] = t1; + return result; +} + +int f(unsigned char t0, unsigned char t1) +{ + struct vec_char_16 a = Dup128VecFromValues(t0, t1); + struct vec_char_16 b; + __builtin_memcpy(&b, &a, sizeof(a)); + return b.raw[0] + b.raw[1]; +} + +/* Ideally we'd optimize this at FRE1 time but we only replace + the loads from b.raw[] with BIT_FIELD_REFs which get optimized + only later in the next FRE. */ +/* { dg-final { scan-tree-dump-not "MEM" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/vla-tert-1.c b/gcc/testsuite/gcc.dg/vla-tert-1.c new file mode 100644 index 0000000..dfbb2e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-tert-1.c @@ -0,0 +1,293 @@ +/* { dg-do run } + * { dg-options "-std=c99" } + * */ + + +// For the conditional operator and variably modified types, +// verify that the size expression on the selected branch +// is evaluated and the correct result is returned. + + +// keep track which side was evaluated. +static int fc[2] = { 0 }; + +static int f(int s, int c) +{ + fc[c]++; + return s; +} + + +int main() +{ + // two VLAs, constant condition + + fc[0] = fc[1] = 0; + + if (5 != sizeof(*(1 ? (char(*)[ f(5, 0) ])0 : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); + + if ((1 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + fc[0] = fc[1] = 0; + + if (3 != sizeof(*(0 ? (char(*)[ f(5, 0) ])0 : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); // fails + + if ((0 != fc[0]) || (1 != fc[1])) + __builtin_abort(); // fails + + // two VLAs + + int c = 0; + fc[0] = fc[1] = 0; + + if (3 != sizeof(*(c ? (char(*)[ f(5, 0) ])0 : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); // fails + + if ((0 != fc[0]) || (1 != fc[1])) + __builtin_abort(); + + c = 1; + fc[0] = fc[1] = 0; + + if (5 != sizeof(*(c ? (char(*)[ f(5, 0) ])0 : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); + + if ((1 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // VLA + array of unknown size, VLA side is evaluated, defined + + c = 0; + fc[0] = fc[1] = 0; + + if (3 != sizeof(*(c ? (char(*)[ ])0 : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); + + if ((0 != fc[0]) || (1 != fc[1])) + __builtin_abort(); + + c = 1; + fc[0] = fc[1] = 0; + + if (5 != sizeof(*(c ? (char(*)[ f(5, 0) ])0 : (char(*)[ ])0))) + __builtin_abort(); + + if ((1 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // VLA + array of unknown size, VLA side is not evaluated + + c = 1; + fc[0] = fc[1] = 0; + + sizeof(*(c ? (char(*)[ ])0 : (char(*)[ f(3, 1) ])0)); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // without sizeof + + fc[0] = fc[1] = 0; + + (c ? (char(*)[ ])0 : (char(*)[ f(3, 1) ])0); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + c = 0; + fc[0] = fc[1] = 0; + + sizeof(*(c ? (char(*)[ f(5, 0) ])0 : (char(*)[ ])0)); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // without sizeof + + fc[0] = fc[1] = 0; + + (c ? (char(*)[ f(5, 0) ])0 : (char(*)[ ])0); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + + // VLA + array of known size, VLA side is evaluated + + c = 0; + fc[0] = fc[1] = 0; + + if (3 != sizeof(*(c ? (char(*)[3])0 : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); + + // sizeof is not evaluated because not a VLA + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + c = 0; + fc[0] = fc[1] = 0; + + // without sizeof + + (c ? (char(*)[3])0 : (char(*)[ f(3, 1) ])0); + + if ((0 != fc[0]) || (1 != fc[1])) + __builtin_abort(); + + c = 1; + fc[0] = fc[1] = 0; + + if (5 != sizeof(*(c ? (char(*)[ f(5, 0) ])0 : (char(*)[5])0))) + __builtin_abort(); + + // sizeof is not evaluated because not a VLA + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // without sizeof + + fc[0] = fc[1] = 0; + + (c ? (char(*)[ f(5, 0) ])0 : (char(*)[ 5 ])0); + + if ((1 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // VLA + array of known size, VLA side is not evaluated + + c = 0; + fc[0] = fc[1] = 0; + + if (3 != sizeof(*(c ? (char(*)[ f(3, 0) ])0 : (char(*)[ 3 ])0))) + __builtin_abort(); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + c = 1; + fc[0] = fc[1] = 0; + + if (5 != sizeof(*(c ? (char(*)[ 5 ])0 : (char(*)[ f(5, 1) ])0))) + __builtin_abort(); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // VM type on one side, null pointer on the other side + + c = 0; + fc[0] = fc[1] = 0; + + if (3 != sizeof(*(c ? (void*)0 : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); + + if ((0 != fc[0]) || (1 != fc[1])) + __builtin_abort(); + + c = 1; + fc[0] = fc[1] = 0; + + if (5 != sizeof(*(c ? (char(*)[ f(5, 0) ])0 : (void*)0))) + __builtin_abort(); + + if ((1 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + +#if 0 + // these cases are not fixable + // VM types on one side, null pointer on the other side + c = 1; + fc[0] = fc[1] = 0; + + if (3 != sizeof(*(c ? (void*)0 : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); + + if ((0 != fc[0]) || (1 != fc[1])) + __builtin_abort(); + + c = 0; + fc[0] = fc[1] = 0; + + if (5 != sizeof(*(c ? (char(*)[ f(5, 0) ])0 : (void*)0))) + __builtin_abort(); + + if ((1 != fc[0]) || (0 != fc[1])) + __builtin_abort(); +#endif + + // VLA + void* + void* p = 0; + c = 0; + fc[0] = fc[1] = 0; + + if (1 != sizeof(*(c ? p : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); + + // not a VLA or evaluated + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // .. without sizeof + + (c ? p : (char(*)[ f(3, 1) ])0); + + if ((0 != fc[0]) || (1 != fc[1])) + __builtin_abort(); + + c = 1; + fc[0] = fc[1] = 0; + + if (1 != sizeof(*(c ? (char(*)[ f(5, 0) ])0 : p))) + __builtin_abort(); + + // not a VLA + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // .. without sizeof + + (c ? (char(*)[ f(5, 0) ])0 : p); + + if ((1 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // VLA + void*, VLA side not evaluated + + c = 1; + fc[0] = fc[1] = 0; + + if (1 != sizeof(*(c ? p : (char(*)[ f(3, 1) ])0))) + __builtin_abort(); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // .. without sizeof + + (c ? p : (char(*)[ f(3, 1) ])0); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + c = 0; + fc[0] = fc[1] = 0; + + if (1 != sizeof(*(c ? (char(*)[ f(5, 0) ])0 : p))) + __builtin_abort(); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + // .. without sizeof + + (c ? (char(*)[ f(5, 0) ])0 : p); + + if ((0 != fc[0]) || (0 != fc[1])) + __builtin_abort(); + + return 0; +} + diff --git a/gcc/testsuite/gcc.target/aarch64/sme/pr121414_1.c b/gcc/testsuite/gcc.target/aarch64/sme/pr121414_1.c new file mode 100644 index 0000000..ad8600f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sme/pr121414_1.c @@ -0,0 +1,27 @@ +#pragma GCC target "+sme2" + +void f1() __arm_streaming_compatible {} +void f2() __arm_streaming {} +void f3() __arm_in("za") {} +void f4() __arm_out("za") {} +void f5() __arm_inout("za") {} +void f6() __arm_in("zt0") {} +void f7() __arm_out("zt0") {} +void f8() __arm_inout("zt0") {} + +__arm_locally_streaming void g1() {} +__arm_new("za") void g2() {} +__arm_new("zt0") void g3() {} + +/* { dg-final { scan-assembler {\t\.variant_pcs\tf1\n} } } */ +/* { dg-final { scan-assembler {\t\.variant_pcs\tf2\n} } } */ +/* { dg-final { scan-assembler {\t\.variant_pcs\tf3\n} } } */ +/* { dg-final { scan-assembler {\t\.variant_pcs\tf4\n} } } */ +/* { dg-final { scan-assembler {\t\.variant_pcs\tf5\n} } } */ +/* { dg-final { scan-assembler {\t\.variant_pcs\tf6\n} } } */ +/* { dg-final { scan-assembler {\t\.variant_pcs\tf7\n} } } */ +/* { dg-final { scan-assembler {\t\.variant_pcs\tf8\n} } } */ + +/* { dg-final { scan-assembler-not {\t\.variant_pcs\tg1\n} } } */ +/* { dg-final { scan-assembler-not {\t\.variant_pcs\tg2\n} } } */ +/* { dg-final { scan-assembler-not {\t\.variant_pcs\tg3\n} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c new file mode 100644 index 0000000..9ca0938 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr120718.c @@ -0,0 +1,12 @@ +/* { dg-options "-O2" } */ + +#include <arm_sve.h> +typedef int __attribute__((vector_size(8))) v2si; +typedef struct { int x; int y; } A; +void bar(A a); +void foo() +{ + A a; + *(v2si *)&a = (v2si){0, (int)svcntd_pat(SV_ALL)}; + bar(a); +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_11.c b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_11.c new file mode 100644 index 0000000..feb7ee7 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_11.c @@ -0,0 +1,20 @@ +/* Peeling for alignment with masking in VLA modes. */ +/* { dg-do compile } */ +/* { dg-options "-Ofast -msve-vector-bits=scalable --param aarch64-autovec-preference=sve-only -fdump-tree-vect-details" } */ + +#define START 3 +#define END 510 + +int __attribute__((noipa)) +foo (int *a) { + for (signed int i = START; i < END; ++i) { + if (a[i] != 0) + return i; + } + return -1; +} + +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ +/* { dg-final { scan-tree-dump "pfa_iv_offset" "vect" } } */ +/* { dg-final { scan-tree-dump "Alignment of access forced using peeling" "vect" } } */ +/* { dg-final { scan-assembler {\tnot\tp[0-7]\.b, p[0-7]/z, p.*\n} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_11_run.c b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_11_run.c new file mode 100644 index 0000000..b4c267f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_11_run.c @@ -0,0 +1,27 @@ +/* Peeling for alignment with masking in VLA modes. */ +/* { dg-do run { target aarch64_sve_hw } } */ +/* { dg-options "-Ofast -msve-vector-bits=scalable --param aarch64-autovec-preference=sve-only" } */ + +#include "peel_ind_11.c" +#include <stdio.h> +#include <stdlib.h> + +#define N 512 + +int __attribute__ ((optimize (1))) +main (void) +{ + for (int k = 5; k < 30; k++) { + int *a = (int *) malloc (sizeof(int) * N); + + /* Set only one non-zero element for test. */ + for (int i = 5; i < 30; i++) + a[i] = (i == k ? 1 : 0); + + int res = foo (a); + asm volatile (""); + if (res != k) { + __builtin_abort (); + } + } +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_12.c b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_12.c new file mode 100644 index 0000000..260482a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_12.c @@ -0,0 +1,21 @@ +/* Peeling for alignment with masking together with versioning in VLA modes. */ +/* { dg-do compile } */ +/* { dg-options "-Ofast -msve-vector-bits=scalable --param aarch64-autovec-preference=sve-only -fdump-tree-vect-details" } */ + +#define START 5 +#define END 509 + +int __attribute__((noipa)) +foo (int *restrict a, int * restrict b) { + for (signed int i = START; i < END; ++i) { + if (a[i] != b[i]) + return i; + } + return -1; +} + +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ +/* { dg-final { scan-tree-dump "pfa_iv_offset" "vect" } } */ +/* { dg-final { scan-tree-dump "Both peeling and versioning will be applied" "vect" } } */ +/* { dg-final { scan-assembler {\tnot\tp[0-7]\.b, p[0-7]/z, p.*\n} } } */ +/* { dg-final { scan-assembler {\teor\t.*\n} } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_12_run.c b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_12_run.c new file mode 100644 index 0000000..ba978fe --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_12_run.c @@ -0,0 +1,29 @@ +/* Peeling for alignment with masking together with versioning in VLA modes. */ +/* { dg-do run { target aarch64_sve_hw } } */ +/* { dg-options "-Ofast -msve-vector-bits=scalable --param aarch64-autovec-preference=sve-only" } */ + +#include "peel_ind_12.c" +#include <stdio.h> +#include <stdlib.h> + +#define N 512 + +int __attribute__ ((optimize (1))) +main (void) { + for (int k = 5; k < 50; k++) { + int *a = (int *) malloc (sizeof(int) * N); + int *b = (int *) malloc (sizeof(int) * N); + + /* Set only one place of different values for test. */ + for (int i = 5; i < 50; i++) { + a[i] = (i == k ? 1 : 0); + b[i] = 0; + } + + int res = foo (a, b); + asm volatile (""); + if (res != k) { + __builtin_abort (); + } + } +} diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_13.c b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_13.c new file mode 100644 index 0000000..730e33e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_13.c @@ -0,0 +1,24 @@ +/* Known inbounds DR in VLA modes. */ +/* { dg-do compile } */ +/* { dg-options "-Ofast -msve-vector-bits=scalable --param aarch64-autovec-preference=sve-only -fdump-tree-vect-details" } */ + +#define N 512 +#define START 5 +#define END 509 + +int x[N] __attribute__((aligned(32))); + +int __attribute__((noipa)) +foo (void) +{ + for (signed int i = START; i < END; ++i) + { + if (x[i] == 0) + return i; + } + return -1; +} + +/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */ +/* { dg-final { scan-tree-dump-not "pfa_iv_offset" "vect" } } */ +/* { dg-final { scan-tree-dump-not "Alignment of access forced using peeling" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_13_run.c b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_13_run.c new file mode 100644 index 0000000..83352a8 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_13_run.c @@ -0,0 +1,15 @@ +/* Known inbounds DR in VLA modes. */ +/* { dg-do run { target aarch64_sve_hw } } */ +/* { dg-options "-Ofast -msve-vector-bits=scalable --param aarch64-autovec-preference=sve-only" } */ + +#include "peel_ind_13.c" + +int __attribute__ ((optimize (1))) +main (void) +{ + int res = foo (); + asm volatile (""); + if (res != START) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr90579.c b/gcc/testsuite/gcc.target/i386/pr90579.c index ab48a44..bd2fd33 100644 --- a/gcc/testsuite/gcc.target/i386/pr90579.c +++ b/gcc/testsuite/gcc.target/i386/pr90579.c @@ -16,8 +16,5 @@ loop (int k, double x) return t; } -/* Verify we end up with scalar loads from r for the final sum. */ -/* { dg-final { scan-assembler "vaddsd\tr\\\+40" } } */ -/* { dg-final { scan-assembler "vaddsd\tr\\\+32" } } */ -/* { dg-final { scan-assembler "vaddsd\tr\\\+24" } } */ -/* { dg-final { scan-assembler "vaddsd\tr\\\+16" } } */ +/* Verify we end up with no loads from r. */ +/* { dg-final { scan-assembler-not "v\[ma\]\[^\t \]+\tr" } } */ diff --git a/gcc/testsuite/gcc.target/s390/bitint-1.c b/gcc/testsuite/gcc.target/s390/bitint-1.c new file mode 100644 index 0000000..8bdf2ae --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/bitint-1.c @@ -0,0 +1,83 @@ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2 -march=z9-109" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* Verify calling convention. */ + +static_assert (sizeof (_BitInt(5)) == 1); +static_assert (sizeof (_BitInt(9)) == 2); +static_assert (sizeof (_BitInt(17)) == 4); +static_assert (sizeof (_BitInt(33)) == 8); + +/* +** bitint5_zero_extend_call: +** lghi %r2,22 +** jg bitint5_zero_extend@PLT +*/ + +void bitint5_zero_extend (unsigned _BitInt(5) x); +void bitint5_zero_extend_call (void) { bitint5_zero_extend (22wbu); } + +/* +** bitint5_sign_extend_call: +** lghi %r2,-10 +** jg bitint5_sign_extend@PLT +*/ + +void bitint5_sign_extend (_BitInt(5) x); +void bitint5_sign_extend_call (void) { bitint5_sign_extend (-10wb); } + +/* +** bitint9_zero_extend_call: +** lghi %r2,422 +** jg bitint9_zero_extend@PLT +*/ + +void bitint9_zero_extend (unsigned _BitInt(9) x); +void bitint9_zero_extend_call (void) { bitint9_zero_extend (422wbu); } + +/* +** bitint9_sign_extend_call: +** lghi %r2,-90 +** jg bitint9_sign_extend@PLT +*/ + +void bitint9_sign_extend (_BitInt(9) x); +void bitint9_sign_extend_call (void) { bitint9_sign_extend (-90wb); } + +/* +** bitint17_zero_extend_call: +** lgfi %r2,108198 +** jg bitint17_zero_extend@PLT +*/ + +void bitint17_zero_extend (unsigned _BitInt(17) x); +void bitint17_zero_extend_call (void) { bitint17_zero_extend (108198wbu); } + +/* +** bitint17_sign_extend_call: +** lghi %r2,-22874 +** jg bitint17_sign_extend@PLT +*/ + +void bitint17_sign_extend (_BitInt(17) x); +void bitint17_sign_extend_call (void) { bitint17_sign_extend (-22874wb); } + +/* +** bitint33_zero_extend_call: +** llihl %r2,1 +** oilf %r2,2795939494 +** jg bitint33_zero_extend@PLT +*/ + +void bitint33_zero_extend (unsigned _BitInt(33) x); +void bitint33_zero_extend_call (void) { bitint33_zero_extend (7090906790wbu); } + +/* +** bitint33_sign_extend_call: +** lgfi %r2,-1499027802 +** jg bitint33_sign_extend@PLT +*/ + +void bitint33_sign_extend (_BitInt(33) x); +void bitint33_sign_extend_call (void) { bitint33_sign_extend (-1499027802wb); } diff --git a/gcc/testsuite/gcc.target/s390/bitint-2.c b/gcc/testsuite/gcc.target/s390/bitint-2.c new file mode 100644 index 0000000..9b0e6b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/bitint-2.c @@ -0,0 +1,32 @@ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23" } */ + +/* Verify calling convention. */ + +static_assert (sizeof (_BitInt(65)) == 16); + +[[gnu::noipa]] void +bitint65_zero_extend (unsigned _BitInt(65) x) +{ + static const char y[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D}; + if (__builtin_memcmp (&x, y, 16) != 0) + __builtin_abort (); +} + +[[gnu::noipa]] void +bitint65_sign_extend (signed _BitInt(65) x) +{ + static const char y[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xBA, 0xDC, 0x0F, 0xFE, 0xE0, 0xDD, 0xF0, 0x0D}; + if (__builtin_memcmp (&x, y, 16) != 0) + __builtin_abort (); +} + +int +main (void) +{ + bitint65_zero_extend (0x1BADC0FFEE0DDF00Dwbu); + bitint65_sign_extend (0x1BADC0FFEE0DDF00Dwb); + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/bitint-3.c b/gcc/testsuite/gcc.target/s390/bitint-3.c new file mode 100644 index 0000000..9132028 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/bitint-3.c @@ -0,0 +1,28 @@ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-march=z9-109 -fdump-rtl-expand" } */ + +/* Verify calling convention. */ + +/* { dg-final { scan-rtl-dump-times "zero_extend:DI.*reg:QI" 1 "expand" } } */ +void bitint5_zero_extend (unsigned _BitInt(5) x); +void bitint5_zero_extend_call (unsigned _BitInt(5) x) { bitint5_zero_extend (x + 1); } + +/* { dg-final { scan-rtl-dump-times "sign_extend:DI.*reg:QI" 1 "expand" } } */ +void bitint5_sign_extend (_BitInt(5) x); +void bitint5_sign_extend_call (_BitInt(5) x) { bitint5_sign_extend (x + 1); } + +/* { dg-final { scan-rtl-dump-times "zero_extend:DI.*reg:HI" 1 "expand" } } */ +void bitint9_zero_extend (unsigned _BitInt(9) x); +void bitint9_zero_extend_call (unsigned _BitInt(9) x) { bitint9_zero_extend (x + 1); } + +/* { dg-final { scan-rtl-dump-times "sign_extend:DI.*reg:HI" 1 "expand" } } */ +void bitint9_sign_extend (_BitInt(9) x); +void bitint9_sign_extend_call (_BitInt(9) x) { bitint9_sign_extend (x + 1); } + +/* { dg-final { scan-rtl-dump-times "zero_extend:DI.*reg:SI" 1 "expand" } } */ +void bitint17_zero_extend (unsigned _BitInt(17) x); +void bitint17_zero_extend_call (unsigned _BitInt(17) x) { bitint17_zero_extend (x + 1); } + +/* { dg-final { scan-rtl-dump-times "sign_extend:DI.*reg:SI" 1 "expand" } } */ +void bitint17_sign_extend (_BitInt(17) x); +void bitint17_sign_extend_call (_BitInt(17) x) { bitint17_sign_extend (x + 1); } diff --git a/gcc/testsuite/gcc.target/s390/bitint-4.c b/gcc/testsuite/gcc.target/s390/bitint-4.c new file mode 100644 index 0000000..dce72d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/bitint-4.c @@ -0,0 +1,71 @@ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-march=z9-109 -O2" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +/* Verify calling convention. */ + +struct s_bitint5 { + short a; + unsigned _BitInt(5) b; + char c; +}; + +static_assert (sizeof (struct s_bitint5) == 4); + +/* +** s_bitint5_call: +** iilf %r2,2758168 +** jg s_bitint5@PLT +*/ + +void s_bitint5 (struct s_bitint5 x); +void s_bitint5_call (void) { s_bitint5 ((struct s_bitint5){42, 22wbu, 24}); } + +struct s_bitint9 { + short a; + unsigned _BitInt(9) b; +}; + +static_assert (sizeof (struct s_bitint9) == 4); + +/* +** s_bitint9_call: +** iilf %r2,2752934 +** jg s_bitint9@PLT +*/ + +void s_bitint9 (struct s_bitint9 x); +void s_bitint9_call (void) { s_bitint9 ((struct s_bitint9){42, 422wbu}); } + +struct s_bitint17 { + int a; + unsigned _BitInt(17) b; +}; + +static_assert (sizeof (struct s_bitint17) == 8); + +/* +** s_bitint17_call: +** llihl %r2,42 +** oilf %r2,108198 +** jg s_bitint17@PLT +*/ + +void s_bitint17 (struct s_bitint17 x); +void s_bitint17_call (void) { s_bitint17 ((struct s_bitint17){42, 108198wbu}); } + +struct s_bitint33 { + unsigned _BitInt(33) b; +}; + +static_assert (sizeof (struct s_bitint33) == 8); + +/* +** s_bitint33_call: +** llihl %r2,1 +** oilf %r2,2795939494 +** jg s_bitint33@PLT +*/ + +void s_bitint33 (struct s_bitint33 x); +void s_bitint33_call (void) { s_bitint33 ((struct s_bitint33){7090906790wbu}); } diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index 00315d1..1c113f8 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -5633,6 +5633,28 @@ visit_nary_op (tree lhs, gassign *stmt) } } break; + case BIT_FIELD_REF: + if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME) + { + tree op0 = TREE_OPERAND (rhs1, 0); + gassign *ass = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op0)); + if (ass + && !gimple_has_volatile_ops (ass) + && vn_get_stmt_kind (ass) == VN_REFERENCE) + { + tree last_vuse = gimple_vuse (ass); + tree op = build3 (BIT_FIELD_REF, TREE_TYPE (rhs1), + gimple_assign_rhs1 (ass), + TREE_OPERAND (rhs1, 1), TREE_OPERAND (rhs1, 2)); + tree result = vn_reference_lookup (op, gimple_vuse (ass), + default_vn_walk_kind, + NULL, true, &last_vuse); + if (result + && useless_type_conversion_p (type, TREE_TYPE (result))) + return set_ssa_val_to (lhs, result); + } + } + break; case TRUNC_DIV_EXPR: if (TYPE_UNSIGNED (type)) break; diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index a9d4aae..a3d3b3e 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -1448,17 +1448,20 @@ vect_compute_data_ref_alignment (vec_info *vinfo, dr_vec_info *dr_info, if (loop_vinfo && dr_safe_speculative_read_required (stmt_info)) { - poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); - auto vectype_size + /* The required target alignment must be a power-of-2 value and is + computed as the product of vector element size, VF and group size. + We compute the constant part first as VF may be a variable. For + variable VF, the power-of-2 check of VF is deferred to runtime. */ + auto align_factor_c = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); - poly_uint64 new_alignment = vf * vectype_size; - /* If we have a grouped access we require that the alignment be N * elem. */ if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) - new_alignment *= DR_GROUP_SIZE (DR_GROUP_FIRST_ELEMENT (stmt_info)); + align_factor_c *= DR_GROUP_SIZE (DR_GROUP_FIRST_ELEMENT (stmt_info)); + + poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); + poly_uint64 new_alignment = vf * align_factor_c; - unsigned HOST_WIDE_INT target_alignment; - if (new_alignment.is_constant (&target_alignment) - && pow2p_hwi (target_alignment)) + if ((vf.is_constant () && pow2p_hwi (new_alignment.to_constant ())) + || (!vf.is_constant () && pow2p_hwi (align_factor_c))) { if (dump_enabled_p ()) { @@ -1467,7 +1470,7 @@ vect_compute_data_ref_alignment (vec_info *vinfo, dr_vec_info *dr_info, dump_dec (MSG_NOTE, new_alignment); dump_printf (MSG_NOTE, " bytes.\n"); } - vector_alignment = target_alignment; + vector_alignment = new_alignment; } } @@ -2438,6 +2441,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) - The cost of peeling (the extra runtime checks, the increase in code size). */ + poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); FOR_EACH_VEC_ELT (datarefs, i, dr) { dr_vec_info *dr_info = loop_vinfo->lookup_dr (dr); @@ -2446,9 +2450,18 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) stmt_vec_info stmt_info = dr_info->stmt; tree vectype = STMT_VINFO_VECTYPE (stmt_info); - do_peeling - = vector_alignment_reachable_p (dr_info, - LOOP_VINFO_VECT_FACTOR (loop_vinfo)); + + /* With variable VF, unsafe speculative read can be avoided for known + inbounds DRs as long as partial vectors are used. */ + if (!vf.is_constant () + && dr_safe_speculative_read_required (stmt_info) + && DR_SCALAR_KNOWN_BOUNDS (dr_info)) + { + dr_set_safe_speculative_read_required (stmt_info, false); + LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P (loop_vinfo) = true; + } + + do_peeling = vector_alignment_reachable_p (dr_info, vf); if (do_peeling) { if (known_alignment_for_access_p (dr_info, vectype)) @@ -2488,7 +2501,6 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) poly_uint64 nscalars = npeel_tmp; if (unlimited_cost_model (LOOP_VINFO_LOOP (loop_vinfo))) { - poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); unsigned group_size = 1; if (STMT_SLP_TYPE (stmt_info) && STMT_VINFO_GROUPED_ACCESS (stmt_info)) @@ -2911,14 +2923,12 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) 2) there is at least one unsupported misaligned data ref with an unknown misalignment, and 3) all misaligned data refs with a known misalignment are supported, and - 4) the number of runtime alignment checks is within reason. - 5) the vectorization factor is a constant. */ + 4) the number of runtime alignment checks is within reason. */ do_versioning = (optimize_loop_nest_for_speed_p (loop) && !loop->inner /* FORNOW */ - && loop_cost_model (loop) > VECT_COST_MODEL_CHEAP) - && LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant (); + && loop_cost_model (loop) > VECT_COST_MODEL_CHEAP); if (do_versioning) { @@ -2965,25 +2975,22 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo) ?? We could actually unroll the loop to achieve the required overall step alignment, and forcing the alignment could be done by doing some iterations of the non-vectorized loop. */ - if (!multiple_p (LOOP_VINFO_VECT_FACTOR (loop_vinfo) - * DR_STEP_ALIGNMENT (dr), + if (!multiple_p (vf * DR_STEP_ALIGNMENT (dr), DR_TARGET_ALIGNMENT (dr_info))) { do_versioning = false; break; } - /* The rightmost bits of an aligned address must be zeros. - Construct the mask needed for this test. For example, - GET_MODE_SIZE for the vector mode V4SI is 16 bytes so the - mask must be 15 = 0xf. */ - gcc_assert (DR_TARGET_ALIGNMENT (dr_info).is_constant ()); - int mask = DR_TARGET_ALIGNMENT (dr_info).to_constant () - 1; + /* Use "mask = DR_TARGET_ALIGNMENT - 1" to test rightmost address + bits for runtime alignment check. For example, for 16 bytes + target alignment the mask is 15 = 0xf. */ + poly_uint64 mask = DR_TARGET_ALIGNMENT (dr_info) - 1; /* FORNOW: use the same mask to test all potentially unaligned references in the loop. */ - if (LOOP_VINFO_PTR_MASK (loop_vinfo) - && LOOP_VINFO_PTR_MASK (loop_vinfo) != mask) + if (maybe_ne (LOOP_VINFO_PTR_MASK (loop_vinfo), 0U) + && maybe_ne (LOOP_VINFO_PTR_MASK (loop_vinfo), mask)) { do_versioning = false; break; diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index 6c1b26a..566308f 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -2454,10 +2454,7 @@ get_misalign_in_elems (gimple **seq, loop_vec_info loop_vinfo) else { tree vla = build_int_cst (type, target_align); - tree vla_align = fold_build2 (BIT_AND_EXPR, type, vla, - fold_build2 (MINUS_EXPR, type, - build_int_cst (type, 0), vla)); - target_align_minus_1 = fold_build2 (MINUS_EXPR, type, vla_align, + target_align_minus_1 = fold_build2 (MINUS_EXPR, type, vla, build_int_cst (type, 1)); } @@ -3840,7 +3837,7 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo, const vec<stmt_vec_info> &may_misalign_stmts = LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo); stmt_vec_info stmt_info; - int mask = LOOP_VINFO_PTR_MASK (loop_vinfo); + poly_uint64 mask = LOOP_VINFO_PTR_MASK (loop_vinfo); tree mask_cst; unsigned int i; tree int_ptrsize_type; @@ -3852,9 +3849,7 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo, tree ptrsize_zero; tree part_cond_expr; - /* Check that mask is one less than a power of 2, i.e., mask is - all zeros followed by all ones. */ - gcc_assert ((mask != 0) && ((mask & (mask+1)) == 0)); + gcc_assert (known_ne (mask, 0U)); int_ptrsize_type = signed_type_for (ptr_type_node); @@ -3962,6 +3957,62 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo, chain_cond_expr (cond_expr, part_cond_expr); } +/* Function vect_create_cond_for_vla_spec_read. + + Create a conditional expression that represents the run-time checks with + max speculative read amount in VLA modes. We check two things: + 1) if the max speculative read amount exceeds the min page size + 2) if the VF is power-of-2 - done by checking the max read amount instead + + Input: + COND_EXPR - input conditional expression. New conditions will be chained + with logical AND operation. + LOOP_VINFO - field LOOP_VINFO_MAX_SPEC_READ_AMOUNT contains the max + possible speculative read amount in VLA modes. + + Output: + COND_EXPR - conditional expression. + + The returned COND_EXPR is the conditional expression to be used in the + if statement that controls which version of the loop gets executed at + runtime. */ + +static void +vect_create_cond_for_vla_spec_read (loop_vec_info loop_vinfo, tree *cond_expr) +{ + poly_uint64 read_amount_poly = LOOP_VINFO_MAX_SPEC_READ_AMOUNT (loop_vinfo); + tree amount = build_int_cst (long_unsigned_type_node, read_amount_poly); + + /* Both the read amount and the VF must be variants, and the read amount must + be a constant power-of-2 multiple of the VF. */ + unsigned HOST_WIDE_INT multiple; + gcc_assert (!read_amount_poly.is_constant () + && !LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant () + && constant_multiple_p (read_amount_poly, + LOOP_VINFO_VECT_FACTOR (loop_vinfo), + &multiple) + && pow2p_hwi (multiple)); + + tree cst_ul_zero = build_int_cstu (long_unsigned_type_node, 0U); + tree cst_ul_one = build_int_cstu (long_unsigned_type_node, 1U); + tree cst_ul_pagesize = build_int_cstu (long_unsigned_type_node, + (unsigned long) param_min_pagesize); + + /* Create an expression of "amount & (amount - 1) == 0". */ + tree amount_m1 = fold_build2 (MINUS_EXPR, long_unsigned_type_node, + amount, cst_ul_one); + tree amount_and_expr = fold_build2 (BIT_AND_EXPR, long_unsigned_type_node, + amount, amount_m1); + tree powof2_cond_expr = fold_build2 (EQ_EXPR, boolean_type_node, + amount_and_expr, cst_ul_zero); + chain_cond_expr (cond_expr, powof2_cond_expr); + + /* Create an expression of "amount <= cst_ul_pagesize". */ + tree pagesize_cond_expr = fold_build2 (LE_EXPR, boolean_type_node, + amount, cst_ul_pagesize); + chain_cond_expr (cond_expr, pagesize_cond_expr); +} + /* If LOOP_VINFO_CHECK_UNEQUAL_ADDRS contains <A1, B1>, ..., <An, Bn>, create a tree representation of: (&A1 != &B1) && ... && (&An != &Bn). Set *COND_EXPR to a tree that is true when both the original *COND_EXPR @@ -4087,6 +4138,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo, gimple_seq gimplify_stmt_list = NULL; tree scalar_loop_iters = LOOP_VINFO_NITERSM1 (loop_vinfo); bool version_align = LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo); + bool version_spec_read = LOOP_REQUIRES_VERSIONING_FOR_SPEC_READ (loop_vinfo); bool version_alias = LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo); bool version_niter = LOOP_REQUIRES_VERSIONING_FOR_NITERS (loop_vinfo); poly_uint64 versioning_threshold @@ -4145,6 +4197,9 @@ vect_loop_versioning (loop_vec_info loop_vinfo, vect_create_cond_for_align_checks (loop_vinfo, &cond_expr, &cond_expr_stmt_list); + if (version_spec_read) + vect_create_cond_for_vla_spec_read (loop_vinfo, &cond_expr); + if (version_alias) { vect_create_cond_for_unequal_addrs (loop_vinfo, &cond_expr); diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index 85f3e90..55a8495 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -1009,6 +1009,7 @@ _loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared) unaligned_dr (NULL), peeling_for_alignment (0), ptr_mask (0), + max_spec_read_amount (0), nonlinear_iv (false), ivexpr_map (NULL), scan_map (NULL), @@ -10141,7 +10142,12 @@ vectorizable_induction (loop_vec_info loop_vinfo, if (peel_mul) { if (!step_mul) - step_mul = peel_mul; + { + gcc_assert (!nunits.is_constant ()); + step_mul = gimple_build (&init_stmts, + MINUS_EXPR, step_vectype, + build_zero_cst (step_vectype), peel_mul); + } else step_mul = gimple_build (&init_stmts, MINUS_EXPR, step_vectype, diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index a6f4db4..dbeb8bd 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -2400,70 +2400,26 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, /* We can only peel for loops, of course. */ gcc_checking_assert (loop_vinfo); + poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); + poly_uint64 read_amount + = vf * TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); + if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) + read_amount *= DR_GROUP_SIZE (DR_GROUP_FIRST_ELEMENT (stmt_info)); + auto target_alignment = DR_TARGET_ALIGNMENT (STMT_VINFO_DR_INFO (stmt_info)); - unsigned HOST_WIDE_INT target_align; - - bool group_aligned = false; - if (target_alignment.is_constant (&target_align) - && nunits.is_constant ()) - { - poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); - auto vectype_size - = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (vectype))); - poly_uint64 required_alignment = vf * vectype_size; - /* If we have a grouped access we require that the alignment be N * elem. */ - if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) - required_alignment *= - DR_GROUP_SIZE (DR_GROUP_FIRST_ELEMENT (stmt_info)); - if (!multiple_p (target_alignment, required_alignment)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "desired alignment %wu not met. Instead got %wu " - "for DR alignment at %G", - required_alignment.to_constant (), - target_align, STMT_VINFO_STMT (stmt_info)); - return false; - } - - if (!pow2p_hwi (target_align)) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "non-power-of-two vector alignment %wd " - "for DR alignment at %G", - target_align, STMT_VINFO_STMT (stmt_info)); - return false; - } - - /* For VLA we have to insert a runtime check that the vector loads - per iterations don't exceed a page size. For now we can use - POLY_VALUE_MAX as a proxy as we can't peel for VLA. */ - if (known_gt (required_alignment, (unsigned)param_min_pagesize)) + if (!multiple_p (target_alignment, read_amount)) + { + if (dump_enabled_p ()) { - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "alignment required for correctness ("); - dump_dec (MSG_MISSED_OPTIMIZATION, required_alignment); - dump_printf (MSG_NOTE, ") may exceed page size\n"); - } - return false; + dump_printf_loc (MSG_NOTE, vect_location, + "desired alignment not met, target was "); + dump_dec (MSG_NOTE, target_alignment); + dump_printf (MSG_NOTE, " previously, but read amount is "); + dump_dec (MSG_NOTE, read_amount); + dump_printf (MSG_NOTE, " at %G.\n", STMT_VINFO_STMT (stmt_info)); } - - group_aligned = true; - } - - /* There are multiple loads that have a misalignment that we couldn't - align. We would need LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P to - vectorize. */ - if (!group_aligned) - { - if (inbounds) - LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P (loop_vinfo) = true; - else - return false; + return false; } /* When using a group access the first element may be aligned but the @@ -2485,6 +2441,33 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, STMT_VINFO_STMT (stmt_info)); return false; } + + /* Reject vectorization if we know the read mount per vector iteration + exceeds the min page size. */ + if (known_gt (read_amount, (unsigned) param_min_pagesize)) + { + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "alignment required for correctness ("); + dump_dec (MSG_MISSED_OPTIMIZATION, read_amount); + dump_printf (MSG_NOTE, ") may exceed page size.\n"); + } + return false; + } + + if (!vf.is_constant ()) + { + /* For VLA modes, we need a runtime check to ensure any speculative + read amount does not exceed the page size. Here we record the max + possible read amount for the check. */ + if (maybe_gt (read_amount, + LOOP_VINFO_MAX_SPEC_READ_AMOUNT (loop_vinfo))) + LOOP_VINFO_MAX_SPEC_READ_AMOUNT (loop_vinfo) = read_amount; + + /* For VLA modes, we must use partial vectors. */ + LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P (loop_vinfo) = true; + } } if (*alignment_support_scheme == dr_unaligned_unsupported) diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 9653496..041cff8 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -919,7 +919,10 @@ public: int peeling_for_alignment; /* The mask used to check the alignment of pointers or arrays. */ - int ptr_mask; + poly_uint64 ptr_mask; + + /* The maximum speculative read amount in VLA modes for runtime check. */ + poly_uint64 max_spec_read_amount; /* Indicates whether the loop has any non-linear IV. */ bool nonlinear_iv; @@ -1155,6 +1158,7 @@ public: #define LOOP_VINFO_RGROUP_IV_TYPE(L) (L)->rgroup_iv_type #define LOOP_VINFO_PARTIAL_VECTORS_STYLE(L) (L)->partial_vector_style #define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask +#define LOOP_VINFO_MAX_SPEC_READ_AMOUNT(L) (L)->max_spec_read_amount #define LOOP_VINFO_LOOP_NEST(L) (L)->shared->loop_nest #define LOOP_VINFO_DATAREFS(L) (L)->shared->datarefs #define LOOP_VINFO_DDRS(L) (L)->shared->ddrs @@ -1209,6 +1213,8 @@ public: #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \ ((L)->may_misalign_stmts.length () > 0) +#define LOOP_REQUIRES_VERSIONING_FOR_SPEC_READ(L) \ + (maybe_gt ((L)->max_spec_read_amount, 0U)) #define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L) \ ((L)->comp_alias_ddrs.length () > 0 \ || (L)->check_unequal_addrs.length () > 0 \ @@ -1219,6 +1225,7 @@ public: (LOOP_VINFO_SIMD_IF_COND (L)) #define LOOP_REQUIRES_VERSIONING(L) \ (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (L) \ + || LOOP_REQUIRES_VERSIONING_FOR_SPEC_READ (L) \ || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (L) \ || LOOP_REQUIRES_VERSIONING_FOR_NITERS (L) \ || LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND (L)) diff --git a/libcpp/directives.cc b/libcpp/directives.cc index 4d06caa..47fb8fb 100644 --- a/libcpp/directives.cc +++ b/libcpp/directives.cc @@ -734,13 +734,30 @@ do_undef (cpp_reader *pfile) if (pfile->cb.undef) pfile->cb.undef (pfile, pfile->directive_line, node); + /* Handle -Wkeyword-macro registered identifiers. */ + bool diagnosed = false; + if (CPP_OPTION (pfile, cpp_warn_keyword_macro) && cpp_keyword_p (node)) + { + if (CPP_OPTION (pfile, cpp_pedantic) + && CPP_OPTION (pfile, cplusplus) + && CPP_OPTION (pfile, lang) >= CLK_GNUCXX26) + cpp_pedwarning (pfile, CPP_W_KEYWORD_MACRO, + "undefining keyword %qs", NODE_NAME (node)); + else + cpp_warning (pfile, CPP_W_KEYWORD_MACRO, + "undefining keyword %qs", NODE_NAME (node)); + diagnosed = true; + } /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier is not currently defined as a macro name. */ if (cpp_macro_p (node)) { if (node->flags & NODE_WARN) - cpp_error (pfile, CPP_DL_WARNING, - "undefining %qs", NODE_NAME (node)); + { + if (!diagnosed) + cpp_error (pfile, CPP_DL_WARNING, + "undefining %qs", NODE_NAME (node)); + } else if (cpp_builtin_macro_p (node) && CPP_OPTION (pfile, warn_builtin_macro_redefined)) cpp_warning (pfile, CPP_W_BUILTIN_MACRO_REDEFINED, diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 75efdcd..bbd88e5 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -620,6 +620,9 @@ struct cpp_options /* True if -finput-charset= option has been used explicitly. */ bool cpp_input_charset_explicit; + /* True if -Wkeyword-macro. */ + bool cpp_warn_keyword_macro; + /* -Wleading-whitespace= value. */ unsigned char cpp_warn_leading_whitespace; @@ -757,7 +760,8 @@ enum cpp_warning_reason { CPP_W_HEADER_GUARD, CPP_W_PRAGMA_ONCE_OUTSIDE_HEADER, CPP_W_LEADING_WHITESPACE, - CPP_W_TRAILING_WHITESPACE + CPP_W_TRAILING_WHITESPACE, + CPP_W_KEYWORD_MACRO }; /* Callback for header lookup for HEADER, which is the name of a @@ -1250,6 +1254,17 @@ inline bool cpp_fun_like_macro_p (cpp_hashnode *node) return cpp_user_macro_p (node) && node->value.macro->fun_like; } +/* Return true for nodes marked for -Wkeyword-macro diagnostics. */ +inline bool cpp_keyword_p (cpp_hashnode *node) +{ + /* As keywords are marked identifiers which don't start with underscore + or start with underscore followed by capital letter (except for + _Pragma). */ + return ((node->flags & NODE_WARN) + && (NODE_NAME (node)[0] != '_' + || (NODE_NAME (node)[1] != '_' && NODE_NAME (node)[1] != 'P'))); +} + extern const unsigned char *cpp_macro_definition (cpp_reader *, cpp_hashnode *); extern const unsigned char *cpp_macro_definition (cpp_reader *, cpp_hashnode *, const cpp_macro *); diff --git a/libcpp/macro.cc b/libcpp/macro.cc index 158c821..a47e1fe 100644 --- a/libcpp/macro.cc +++ b/libcpp/macro.cc @@ -3411,7 +3411,11 @@ warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node, { /* Some redefinitions need to be warned about regardless. */ if (node->flags & NODE_WARN) - return true; + { + /* Ignore NODE_WARN on -Wkeyword-macro registered identifiers though. */ + if (!CPP_OPTION (pfile, cpp_warn_keyword_macro) || !cpp_keyword_p (node)) + return true; + } /* Suppress warnings for builtins that lack the NODE_WARN flag, unless Wbuiltin-macro-redefined. */ @@ -3949,6 +3953,25 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node, if (name_loc) macro->line = name_loc; + /* Handle -Wkeyword-macro registered identifiers. */ + if (CPP_OPTION (pfile, cpp_warn_keyword_macro) && cpp_keyword_p (node)) + { + if (macro->fun_like + && CPP_OPTION (pfile, cplusplus) + && (strcmp ((const char *) NODE_NAME (node), "likely") == 0 + || strcmp ((const char *) NODE_NAME (node), "unlikely") == 0)) + /* likely and unlikely can be defined as function-like macros. */; + else if (CPP_OPTION (pfile, cpp_pedantic) + && CPP_OPTION (pfile, cplusplus) + && CPP_OPTION (pfile, lang) >= CLK_GNUCXX26) + cpp_pedwarning_with_line (pfile, CPP_W_KEYWORD_MACRO, macro->line, 0, + "keyword %qs defined as macro", + NODE_NAME (node)); + else + cpp_warning_with_line (pfile, CPP_W_KEYWORD_MACRO, macro->line, 0, + "keyword %qs defined as macro", + NODE_NAME (node)); + } if (cpp_macro_p (node)) { if (CPP_OPTION (pfile, warn_unused_macros)) @@ -3957,12 +3980,12 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node, if (warn_of_redefinition (pfile, node, macro)) { const enum cpp_warning_reason reason - = (cpp_builtin_macro_p (node) && !(node->flags & NODE_WARN)) - ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE; + = (cpp_builtin_macro_p (node) && !(node->flags & NODE_WARN) + ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE); bool warned - = cpp_pedwarning_with_line (pfile, reason, macro->line, 0, - "%qs redefined", NODE_NAME (node)); + = cpp_pedwarning_with_line (pfile, reason, macro->line, 0, + "%qs redefined", NODE_NAME (node)); if (warned && cpp_user_macro_p (node)) cpp_error_with_line (pfile, CPP_DL_NOTE, node->value.macro->line, diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 0962ddf..882117d 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2025-08-06 Jakub Jelinek <jakub@redhat.com> + + PR libgcc/121397 + * enable-execute-stack-mprotect.c (check_enabling): Remove useless + forward declaration. + 2025-07-31 Wilco Dijkstra <wilco.dijkstra@arm.com> * config/aarch64/cpuinfo.c (__init_cpu_features_constructor): diff --git a/libgcc/config.host b/libgcc/config.host index d36f0e3..92acdd0 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -1397,6 +1397,8 @@ s390x-*-linux*) tmake_file="${tmake_file} s390/t-crtstuff s390/t-linux t-stack s390/t-stack-s390" if test "${host_address}" = 32; then tmake_file="${tmake_file} s390/32/t-floattodi" + else + tmake_file="${tmake_file} s390/t-softfp t-softfp" fi md_unwind_header=s390/linux-unwind.h ;; diff --git a/libgcc/config/s390/libgcc-glibc.ver b/libgcc/config/s390/libgcc-glibc.ver index 86c55a0..00375b3 100644 --- a/libgcc/config/s390/libgcc-glibc.ver +++ b/libgcc/config/s390/libgcc-glibc.ver @@ -114,3 +114,17 @@ GCC_4.1.0 { __floatditf %endif } + +%ifdef __s390x__ +%inherit GCC_16.0.0 GCC_4.1.0 +GCC_16.0.0 { + __mulbitint3 + __divmodbitint4 + __fixsfbitint + __fixdfbitint + __fixtfbitint + __floatbitintsf + __floatbitintdf + __floatbitinttf +} +%endif diff --git a/libgcc/config/s390/sfp-exceptions.c b/libgcc/config/s390/sfp-exceptions.c new file mode 100644 index 0000000..a2fc5dd --- /dev/null +++ b/libgcc/config/s390/sfp-exceptions.c @@ -0,0 +1,61 @@ +/* Copyright (C) 2001-2025 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/>. */ + +#include "sfp-machine.h" + +#define __math_force_eval_div(x, y) \ + do { asm ("" : "+f" (x)); asm volatile ("" : : "f" (x / y)); } while (0) + +void +__sfp_handle_exceptions (int _fex) +{ + if (_fex & FP_EX_INVALID) + { + float x = 0.0f; + __math_force_eval_div (x, x); + } + if (_fex & FP_EX_DIVZERO) + { + float x = 1.0f; + float y = 0.0f; + __math_force_eval_div (x, y); + } + if (_fex & FP_EX_OVERFLOW) + { + float x = __FLT_MAX__; + asm ("" : "+f" (x)); + asm volatile ("" : : "f" (x + x)); + } + if (_fex & FP_EX_UNDERFLOW) + { + float x = __FLT_MIN__; + asm ("" : "+f" (x)); + asm volatile ("" : : "f" (x * x)); + } + if (_fex & FP_EX_INEXACT) + { + float x = 1.0f; + float y = 3.0f; + __math_force_eval_div (x, y); + } +} diff --git a/libgcc/config/s390/sfp-machine.h b/libgcc/config/s390/sfp-machine.h new file mode 100644 index 0000000..960bad7 --- /dev/null +++ b/libgcc/config/s390/sfp-machine.h @@ -0,0 +1,89 @@ +/* Copyright (C) 2001-2025 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/>. */ + +#if ! __s390x__ +# error "soft-fp implemented for s390x only" +#endif + +#define _FP_W_TYPE_SIZE 64 +#define _FP_W_TYPE unsigned long long +#define _FP_WS_TYPE signed long long +#define _FP_I_TYPE long long + +typedef int TItype __attribute__ ((mode (TI))); +typedef unsigned int UTItype __attribute__ ((mode (TI))); +#define TI_BITS (__CHAR_BIT__ * (int) sizeof (TItype)) + +#define _FP_NANFRAC_H ((_FP_QNANBIT_H << 1) - 1) +#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) +#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1) +#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1 + +#define _FP_NANSIGN_H 0 +#define _FP_NANSIGN_S 0 +#define _FP_NANSIGN_D 0 +#define _FP_NANSIGN_Q 0 + +#define _FP_KEEPNANFRACP 1 +#define _FP_QNANNEGATEDP 0 + +#define FP_EX_INVALID 0x01 +#define FP_EX_DIVZERO 0x02 +#define FP_EX_OVERFLOW 0x04 +#define FP_EX_UNDERFLOW 0x08 +#define FP_EX_INEXACT 0x10 +#define FP_EX_ALL \ + (FP_EX_INVALID | FP_EX_DIVZERO | FP_EX_OVERFLOW \ + | FP_EX_UNDERFLOW | FP_EX_INEXACT) + +void __sfp_handle_exceptions (int); + +#define FP_HANDLE_EXCEPTIONS \ + do { \ + if (__builtin_expect (_fex, 0)) \ + __sfp_handle_exceptions (_fex); \ + } while (0) + +#define _FP_TININESS_AFTER_ROUNDING 0 + +#define FP_RND_NEAREST 0x0 +#define FP_RND_ZERO 0x1 +#define FP_RND_PINF 0x2 +#define FP_RND_MINF 0x3 +#define FP_RND_MASK 0x3 + +#define _FP_DECL_EX \ + unsigned int _fpcr __attribute__ ((unused)) = FP_RND_NEAREST + +#define FP_INIT_ROUNDMODE \ + do { \ + __asm__ __volatile__ ("stfpc %0" \ + : "=m" (_fpcr)); \ + } while (0) + +#define FP_ROUNDMODE (_fpcr & FP_RND_MASK) + +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 + +#define __BYTE_ORDER __BIG_ENDIAN diff --git a/libgcc/config/s390/t-softfp b/libgcc/config/s390/t-softfp new file mode 100644 index 0000000..724b15e --- /dev/null +++ b/libgcc/config/s390/t-softfp @@ -0,0 +1,2 @@ +LIB2ADD += $(srcdir)/config/s390/sfp-exceptions.c +softfp_extras := fixtfbitint floatbitinttf diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index ea41616..440a32a 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,10 @@ +2025-08-06 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libfortran/121234 + * io/list_read.c (read_character): Add checks to bypass eating + semicolons when reading strings with decimal mode 'point' + (list_formatted_read_scalar): Likewise. + 2025-07-30 Yuao Ma <c8ef@outlook.com> * gfortran.map: Add split symbol. diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 2689f3e..722da76 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,23 @@ +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + + * target.c (gomp_update): Call gomp_merge_iterator_maps. Free + allocated variables. + * testsuite/libgomp.c-c++-common/target-update-iterators-1.c: New. + * testsuite/libgomp.c-c++-common/target-update-iterators-2.c: New. + * testsuite/libgomp.c-c++-common/target-update-iterators-3.c: New. + +2025-08-06 Kwok Cheung Yeung <kcyeung@baylibre.com> + Andrew Stubbs <ams@baylibre.com> + + * target.c (kind_to_name): New. + (gomp_merge_iterator_maps): New. + (gomp_map_vars_internal): Call gomp_merge_iterator_maps. Copy + address of only the first iteration to target vars. Free allocated + variables. + * testsuite/libgomp.c-c++-common/target-map-iterators-1.c: New. + * testsuite/libgomp.c-c++-common/target-map-iterators-2.c: New. + * testsuite/libgomp.c-c++-common/target-map-iterators-3.c: New. + 2025-07-21 Thomas Schwinge <tschwinge@baylibre.com> PR target/119853 diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index cf90917..b072d0b 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,8 @@ +2025-08-06 Matthieu Longo <matthieu.longo@arm.com> + + * testsuite/test-doubly-linked-list.c: disable debug logging on + stdout. + 2025-07-09 Matthieu Longo <matthieu.longo@arm.com> * Makefile.in: Add new header. diff --git a/libiberty/testsuite/test-doubly-linked-list.c b/libiberty/testsuite/test-doubly-linked-list.c index 1e1fc63..93fe19a 100644 --- a/libiberty/testsuite/test-doubly-linked-list.c +++ b/libiberty/testsuite/test-doubly-linked-list.c @@ -155,19 +155,26 @@ bool check(const char *op, bool success = true; bool res; - l_print (wrapper->first); +#define DUMP_LIST 0 + + if (DUMP_LIST) + l_print (wrapper->first); + res = run_test (expect, wrapper, false); printf ("%s: test-linked-list::%s: check forward conformity\n", res ? "PASS": "FAIL", op); success &= res; - l_reverse_print (wrapper->last); + if (DUMP_LIST) + l_reverse_print (wrapper->last); + res = run_test (expect, wrapper, true); printf ("%s: test-linked-list::%s: check backward conformity\n", res ? "PASS": "FAIL", op); success &= res; - printf("\n"); + if (DUMP_LIST) + printf("\n"); return success; } diff --git a/libstdc++-v3/doc/html/manual/appendix_porting.html b/libstdc++-v3/doc/html/manual/appendix_porting.html index 887fa50..7b63613 100644 --- a/libstdc++-v3/doc/html/manual/appendix_porting.html +++ b/libstdc++-v3/doc/html/manual/appendix_porting.html @@ -26,7 +26,7 @@ Support for C++11 dialect. </a></span></dt><dt><span class="section"><a href="backwards.html#backwards.third.iterator_type"> <code class="code">Container::iterator_type</code> is not necessarily <code class="code">Container::value_type*</code> </a></span></dt></dl></dd></dl></dd></dl></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="appendix.porting.build_hacking"></a>Configure and Build Hacking</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="build_hacking.prereq"></a>Prerequisites</h3></div></div></div><p> - As noted <a class="link" href="http://gcc.gnu.org/install/prerequisites.html" target="_top">previously</a>, + As noted <a class="link" href="https://gcc.gnu.org/install/prerequisites.html" target="_top">previously</a>, certain other tools are necessary for hacking on files that control configure (<code class="code">configure.ac</code>, <code class="code">acinclude.m4</code>) and make diff --git a/libstdc++-v3/doc/xml/manual/build_hacking.xml b/libstdc++-v3/doc/xml/manual/build_hacking.xml index 20de49f..4c044d9 100644 --- a/libstdc++-v3/doc/xml/manual/build_hacking.xml +++ b/libstdc++-v3/doc/xml/manual/build_hacking.xml @@ -17,7 +17,7 @@ <section xml:id="build_hacking.prereq"><info><title>Prerequisites</title></info> <para> - As noted <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/install/prerequisites.html">previously</link>, + As noted <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://gcc.gnu.org/install/prerequisites.html">previously</link>, certain other tools are necessary for hacking on files that control configure (<code>configure.ac</code>, <code>acinclude.m4</code>) and make |