diff options
107 files changed, 7162 insertions, 602 deletions
@@ -1,3 +1,7 @@ +2025-08-05 Thomas Schwinge <tschwinge@baylibre.com> + + * .gitignore: Remove 'libgrust/*/target/'. + 2025-08-01 Luis Machado <luis.machado.foss@gmail.com> * MAINTAINERS: Update my e-mail address. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4b6bc90..b600551 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,352 @@ +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 + * config/i386/i386-expand.cc (ix86_expand_set_or_cpymem): Use + STORE_MAX_PIECES to get the widest vector mode in vector loop + for memset. + +2025-08-05 Georg-Johann Lay <avr@gjlay.de> + + * config/avr/avr.cc (avr_rtx_costs_1) [SIGN_EXTEND]: Adjust cost. + * config/avr/avr.md (*sext.ashift<QIPSI:mode><HISI:mode>2): New + insn and a cc split. + +2025-08-05 Richard Sandiford <richard.sandiford@arm.com> + + PR target/121306 + * config/i386/predicates.md (extract_operator): Replace with... + (extract_high_operator): ...this new predicate. + * config/i386/i386.md (*cmpqi_ext<mode>_1, *cmpqi_ext<mode>_2) + (*cmpqi_ext<mode>_3, *cmpqi_ext<mode>_4, *movstrictqi_ext<mode>_1) + (*extzv<mode>, *insvqi_2, *extendqi<SWI24:mode>_ext_1) + (*addqi_ext<mode>_1_slp, *addqi_ext<mode>_1_slp, *addqi_ext<mode>_0) + (*addqi_ext2<mode>_0, *addqi_ext<mode>_1, *<insn>qi_ext<mode>_2) + (*subqi_ext<mode>_1_slp, *subqi_ext<mode>_2_slp, *subqi_ext<mode>_0) + (*subqi_ext2<mode>_0, *subqi_ext<mode>_1, *testqi_ext<mode>_1) + (*testqi_ext<mode>_2, *<code>qi_ext<mode>_1_slp) + (*<code>qi_ext<mode>_2_slp. *<code>qi_ext<mode>_0) + (*<code>qi_ext2<mode>_0, *<code>qi_ext<mode>_1) + (*<code>qi_ext<mode>_1_cc, *<code>qi_ext<mode>_1_cc) + (*<code>qi_ext<mode>_2, *<code>qi_ext<mode>_3, *negqi_ext<mode>_1) + (*one_cmplqi_ext<mode>_1, *ashlqi_ext<mode>_1, *<insn>qi_ext<mode>_1) + (define_peephole2): Replace uses of extract_operator with + extract_high_operator, matching only the first operand. + Use zero_extract rather than match_op_dup when splitting. + +2025-08-05 Richard Biener <rguenther@suse.de> + + * tree-vectorizer.h (vect_relevant::hybrid): Remove. + * tree-vect-loop.cc (vect_analyze_loop_2): Do not call + vect_detect_hybrid_slp. + * tree-vect-slp.cc (maybe_push_to_hybrid_worklist): Remove. + (vect_detect_hybrid_slp): Likewise. + +2025-08-05 Georg-Johann Lay <avr@gjlay.de> + + PR target/121359 + * config/avr/avr.h: Remove -mlra and remains of reload. + * config/avr/avr.cc: Same. + * config/avr/avr.md: Same. + * config/avr/avr-log.cc: Same. + * config/avr/avr-protos.h: Same. + * config/avr/avr.opt: Same. + * config/avr/avr.opt.urls: Same. + +2025-08-05 H.J. Lu <hjl.tools@gmail.com> + + PR target/121306 + * config/i386/i386.md (*one_cmplqi_ext<mode>_1): Updated to + support the new pattern. + +2025-08-05 Richard Biener <rguenther@suse.de> + + PR tree-optimization/121395 + * tree-vectorizer.h (_loop_vec_info::alternate_defs): New member. + (LOOP_VINFO_ALTERNATE_DEFS): New. + * tree-vect-stmts.cc (vect_stmt_relevant_p): Populate it. + (vectorizable_simd_clone_call): Do not register a SLP def + when there is none. + * tree-vect-slp.cc (vect_build_slp_tree_1): Allow a NULL + vectype when there's no LHS. Allow all calls w/o LHS. + (vect_analyze_slp): Process LOOP_VINFO_ALTERNATE_DEFS as + SLP graph entries. + (vect_make_slp_decision): Handle a NULL SLP_TREE_VECTYPE. + (vect_slp_analyze_node_operations_1): Likewise. + (vect_schedule_slp_node): Likewise. + +2025-08-05 Richard Biener <rguenther@suse.de> + + * tree-vectorizer.h (enum slp_vect_type): Rename loop_vect + to not_vect, clarify docs. + (HYBRID_SLP_STMT): Remove. + * tree-vectorizer.cc (vec_info::new_stmt_vec_info): Adjust. + * tree-vect-loop.cc (vect_analyze_loop_2): Likewise. + +2025-08-05 Richard Biener <rguenther@suse.de> + + * tree-vect-data-refs.cc (vect_get_data_access_cost): Use + ncopies == 1. + * tree-vect-slp.cc (vect_remove_slp_scalar_calls): Remove + hybrid/loop SLP skip. + * tree-vect-stmts.cc (vectorizable_store): Remove pure SLP assert. + +2025-08-05 Richard Biener <rguenther@suse.de> + + PR tree-optimization/121382 + * tree-ssa-loop-ivopts.cc (create_new_iv): Rewrite the IV + step to defined form. + +2025-08-05 Richard Biener <rguenther@suse.de> + + PR tree-optimization/121370 + * tree-scalar-evolution.cc (scev_dfs::add_to_evolution_1): + Avoid UB integer overflow in accumulating CHREC_RIGHT. + +2025-08-05 Yang Yujie <yangyujie@loongson.cn> + + * expr.cc (expand_expr_real_1): Do not call + reduce_to_bit_field_precision if the target assumes the _BitInt + results to be already extended. + (EXTEND_BITINT): Same. + * expr.h (bitint_extended): Declare the cache variable. + * function.cc (prepare_function_start): Initialize it. + +2025-08-05 Yang Yujie <yangyujie@loongson.cn> + + * explow.cc (promote_function_mode): Add a case for + small/medium _BitInts. + (promote_mode): Same. + +2025-08-05 Gerald Pfeifer <gerald@pfeifer.com> + + PR target/69374 + * doc/install.texi (Configuration): Mark up atexit as code. + +2025-08-05 Pan Li <pan2.li@intel.com> + + * config/riscv/riscv.cc (riscv_expand_xmode_usmul): Take + umulhu for high bits mul result. + 2025-08-04 Hans-Peter Nilsson <hp@bitrange.com> * defaults.h (MAX_FIXED_MODE_SIZE): Default to 2 * BITS_PER_WORD diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 3724f15..d4024d7 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20250805 +20250807 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index d7d5cbe..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 @@ -3402,6 +3400,9 @@ gengtype-lex.cc : gengtype-lex.l echo '#else' >> $@.tmp; \ echo '#include "bconfig.h"' >> $@.tmp; \ echo '#endif' >> $@.tmp; \ + echo '#define FLEX_SCANNER' >> $@.tmp; \ + echo '#include "system.h"' >> $@.tmp; \ + echo '#undef FLEX_SCANNER' >> $@.tmp; \ cat $@ >> $@.tmp; \ mv $@.tmp $@; \ } 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/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-parser.cc b/gcc/c/c-parser.cc index 4a13fc0..814accf 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -16659,7 +16659,7 @@ c_parser_omp_variable_list (c_parser *parser, || CONVERT_EXPR_P (decl)) decl = TREE_OPERAND (decl, 0); - tree u = build_omp_clause (clause_loc, kind); + tree u = build_omp_clause (loc, kind); OMP_CLAUSE_DECL (u) = decl; OMP_CLAUSE_CHAIN (u) = list; list = u; @@ -20072,7 +20072,7 @@ c_parser_omp_clause_doacross (c_parser *parser, tree list) map ( [map-type-modifier[,] ...] map-kind: variable-list ) map-type-modifier: - always | close */ + always | close | present | iterator (iterators-definition) */ static tree c_parser_omp_clause_map (c_parser *parser, tree list, bool declare_mapper_p) @@ -20087,15 +20087,35 @@ c_parser_omp_clause_map (c_parser *parser, tree list, bool declare_mapper_p) int pos = 1; int map_kind_pos = 0; - while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME) + int iterator_length = 0; + for (;;) { - if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON) + c_token *tok = c_parser_peek_nth_token_raw (parser, pos); + if (tok->type != CPP_NAME) + break; + + const char *p = IDENTIFIER_POINTER (tok->value); + c_token *next_tok = c_parser_peek_nth_token_raw (parser, pos + 1); + if (strcmp (p, "iterator") == 0 && next_tok->type == CPP_OPEN_PAREN) + { + unsigned n = pos + 2; + if (c_parser_check_balanced_raw_token_sequence (parser, &n) + && c_parser_peek_nth_token_raw (parser, n)->type + == CPP_CLOSE_PAREN) + { + iterator_length = n - pos + 1; + pos = n; + next_tok = c_parser_peek_nth_token_raw (parser, pos + 1); + } + } + + if (next_tok->type == CPP_COLON) { map_kind_pos = pos; break; } - if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA) + if (next_tok->type == CPP_COMMA) pos++; else if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_OPEN_PAREN) @@ -20117,6 +20137,7 @@ c_parser_omp_clause_map (c_parser *parser, tree list, bool declare_mapper_p) int present_modifier = 0; int mapper_modifier = 0; tree mapper_name = NULL_TREE; + tree iterators = NULL_TREE; for (int pos = 1; pos < map_kind_pos; ++pos) { c_token *tok = c_parser_peek_token (parser); @@ -20150,6 +20171,17 @@ c_parser_omp_clause_map (c_parser *parser, tree list, bool declare_mapper_p) close_modifier++; c_parser_consume_token (parser); } + else if (strcmp ("iterator", p) == 0) + { + if (iterators) + { + c_parser_error (parser, "too many %<iterator%> modifiers"); + parens.skip_until_found_close (parser); + return list; + } + iterators = c_parser_omp_iterators (parser); + pos += iterator_length - 1; + } else if (strcmp ("mapper", p) == 0) { c_parser_consume_token (parser); @@ -20223,8 +20255,8 @@ c_parser_omp_clause_map (c_parser *parser, tree list, bool declare_mapper_p) else { c_parser_error (parser, "%<map%> clause with map-type modifier other " - "than %<always%>, %<close%>, %<mapper%> or " - "%<present%>"); + "than %<always%>, %<close%>, %<iterator%>, " + "%<mapper%> or %<present%>"); parens.skip_until_found_close (parser); return list; } @@ -20273,9 +20305,19 @@ c_parser_omp_clause_map (c_parser *parser, tree list, bool declare_mapper_p) tree last_new = NULL_TREE; + if (iterators) + { + tree block = pop_scope (); + if (iterators == error_mark_node) + iterators = NULL_TREE; + else + TREE_VEC_ELT (iterators, 5) = block; + } + for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) { OMP_CLAUSE_SET_MAP_KIND (c, kind); + OMP_CLAUSE_ITERATORS (c) = iterators; last_new = c; } @@ -20534,8 +20576,11 @@ c_parser_omp_clause_device_type (c_parser *parser, tree list) to ( variable-list ) OpenMP 5.1: - from ( [present :] variable-list ) - to ( [present :] variable-list ) */ + from ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list ) + to ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list ) + + motion-modifier: + present | iterator (iterators-definition) */ static tree c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind, @@ -20546,18 +20591,85 @@ c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind, if (!parens.require_open (parser)) return list; + int pos = 1, colon_pos = 0; + int iterator_length = 0; + + while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME) + { + const char *identifier = + IDENTIFIER_POINTER (c_parser_peek_nth_token_raw (parser, pos)->value); + if (c_parser_peek_nth_token_raw (parser, pos + 1)->type + == CPP_OPEN_PAREN) + { + unsigned int npos = pos + 2; + if (c_parser_check_balanced_raw_token_sequence (parser, &npos) + && (c_parser_peek_nth_token_raw (parser, npos)->type + == CPP_CLOSE_PAREN)) + { + if (strcmp (identifier, "iterator") == 0) + iterator_length = npos - pos + 1; + pos = npos; + } + } + if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA) + pos += 2; + else + pos++; + if (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_COLON) + { + colon_pos = pos; + break; + } + } + bool present = false; - c_token *token = c_parser_peek_token (parser); + tree iterators = NULL_TREE; - if (token->type == CPP_NAME - && strcmp (IDENTIFIER_POINTER (token->value), "present") == 0 - && c_parser_peek_2nd_token (parser)->type == CPP_COLON) + for (int pos = 1; pos < colon_pos; ++pos) { - present = true; - c_parser_consume_token (parser); - c_parser_consume_token (parser); + c_token *token = c_parser_peek_token (parser); + if (token->type == CPP_COMMA) + { + c_parser_consume_token (parser); + continue; + } + const char *p = IDENTIFIER_POINTER (token->value); + if (strcmp ("present", p) == 0) + { + if (present) + { + c_parser_error (parser, "too many %<present%> modifiers"); + parens.skip_until_found_close (parser); + return list; + } + present = true; + c_parser_consume_token (parser); + } + else if (strcmp ("iterator", p) == 0) + { + if (iterators) + { + c_parser_error (parser, "too many %<iterator%> modifiers"); + parens.skip_until_found_close (parser); + return list; + } + iterators = c_parser_omp_iterators (parser); + pos += iterator_length - 1; + } + else + { + error_at (token->location, + "%qs clause with modifier other than %<iterator%> or " + "%<present%>", + kind == OMP_CLAUSE_TO ? "to" : "from"); + parens.skip_until_found_close (parser); + return list; + } } + if (colon_pos) + c_parser_require (parser, CPP_COLON, "expected %<:%>"); + tree nl = c_parser_omp_variable_list (parser, loc, kind, list); parens.skip_until_found_close (parser); @@ -20565,6 +20677,19 @@ c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind, for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) OMP_CLAUSE_MOTION_PRESENT (c) = 1; + if (iterators) + { + tree block = pop_scope (); + if (iterators == error_mark_node) + iterators = NULL_TREE; + else + TREE_VEC_ELT (iterators, 5) = block; + } + + if (iterators) + for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_ITERATORS (c) = iterators; + return nl; } 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 ed6e56e..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)); - 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); + tree d = fold_build3_loc (UNKNOWN_LOCATION, COND_EXPR, sizetype, + cond, TYPE_MAX_VALUE (d1), + TYPE_MAX_VALUE (d2)); + + 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)); @@ -1970,6 +1999,9 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2, ft2 = DECL_BIT_FIELD_TYPE (s2); } + if (!ft1 || !ft2) + return false; + if (TREE_CODE (ft1) == ERROR_MARK || TREE_CODE (ft2) == ERROR_MARK) return false; @@ -2648,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. */ @@ -4926,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); } @@ -5271,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); @@ -5727,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); @@ -6380,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)) @@ -7337,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; @@ -12730,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))) { @@ -14390,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 " @@ -14529,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, @@ -15356,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; } @@ -16204,7 +16292,14 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* We've reached the end of a list of expanded nodes. Reset the group start pointer. */ if (c == grp_sentinel) - grp_start_p = NULL; + { + if (grp_start_p + && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p)) + for (tree gc = *grp_start_p; gc != grp_sentinel; + gc = OMP_CLAUSE_CHAIN (gc)) + OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p); + grp_start_p = NULL; + } switch (OMP_CLAUSE_CODE (c)) { @@ -16962,6 +17057,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* FALLTHRU */ case OMP_CLAUSE_TO: case OMP_CLAUSE_FROM: + if (OMP_CLAUSE_ITERATORS (c) + && c_omp_finish_iterators (OMP_CLAUSE_ITERATORS (c))) + { + t = error_mark_node; + break; + } + /* FALLTHRU */ case OMP_CLAUSE__CACHE_: { using namespace omp_addr_tokenizer; @@ -17690,6 +17792,11 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) pc = &OMP_CLAUSE_CHAIN (c); } + if (grp_start_p + && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p)) + for (tree gc = *grp_start_p; gc; gc = OMP_CLAUSE_CHAIN (gc)) + OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p); + if (simdlen && safelen && tree_int_cst_lt (OMP_CLAUSE_SAFELEN_EXPR (safelen), diff --git a/gcc/common.opt b/gcc/common.opt index 70659fa..bf38f60 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1067,6 +1067,8 @@ Driver Undocumented ; ; 21: Fix noexcept lambda capture pruning. ; Fix C++20 layout of base with all explicitly defaulted constructors. +; Fix mangling of class and array objects with implicitly +; zero-initialized non-trailing subojects. ; Default in G++ 16. ; ; Additional positive integers will be assigned as new versions of diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index da3cb9f..f2ede07 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -1758,6 +1758,11 @@ riscv_expand_arch (int argc, { gcc_assert (argc == 1); location_t loc = UNKNOWN_LOCATION; + + /* Filter out -march=unset, it will expand from -mcpu later. */ + if (strcmp (argv[0], "unset") == 0) + return ""; + /* Try to interpret the arch as CPU first. */ const char *arch_str = riscv_expand_arch_from_cpu (argc, argv); if (!strlen (arch_str)) 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/riscv/arch-canonicalize b/gcc/config/riscv/arch-canonicalize index 34dad45..5d24f5ed 100755 --- a/gcc/config/riscv/arch-canonicalize +++ b/gcc/config/riscv/arch-canonicalize @@ -20,77 +20,314 @@ # along with GCC; see the file COPYING3. If not see # <http://www.gnu.org/licenses/>. -# TODO: Extract riscv_subset_t from riscv-common.cc and make it can be compiled -# standalone to replace this script, that also prevents us implementing -# that twice and keep sync again and again. - from __future__ import print_function import sys import argparse import collections import itertools +import re +import os from functools import reduce SUPPORTED_ISA_SPEC = ["2.2", "20190608", "20191213"] CANONICAL_ORDER = "imafdqlcbkjtpvnh" LONG_EXT_PREFIXES = ['z', 's', 'h', 'x'] +def parse_define_riscv_ext(content): + """Parse DEFINE_RISCV_EXT macros using position-based parsing.""" + extensions = [] + + # Find all DEFINE_RISCV_EXT blocks + pattern = r'DEFINE_RISCV_EXT\s*\(' + matches = [] + + pos = 0 + while True: + match = re.search(pattern, content[pos:]) + if not match: + break + + start_pos = pos + match.start() + paren_count = 0 + current_pos = pos + match.end() - 1 # Start at the opening parenthesis + + # Find the matching closing parenthesis + while current_pos < len(content): + if content[current_pos] == '(': + paren_count += 1 + elif content[current_pos] == ')': + paren_count -= 1 + if paren_count == 0: + break + current_pos += 1 + + if paren_count == 0: + # Extract the content inside parentheses + macro_content = content[pos + match.end():current_pos] + ext_data = parse_macro_arguments(macro_content) + if ext_data: + extensions.append(ext_data) + + pos = current_pos + 1 + + return extensions + +def parse_macro_arguments(macro_content): + """Parse the arguments of a DEFINE_RISCV_EXT macro.""" + # Remove comments /* ... */ + cleaned_content = re.sub(r'/\*[^*]*\*/', '', macro_content) + + # Split arguments by comma, but respect nested structures + args = [] + current_arg = "" + paren_count = 0 + brace_count = 0 + in_string = False + escape_next = False + + for char in cleaned_content: + if escape_next: + current_arg += char + escape_next = False + continue + + if char == '\\': + escape_next = True + current_arg += char + continue + + if char == '"' and not escape_next: + in_string = not in_string + current_arg += char + continue + + if in_string: + current_arg += char + continue + + if char == '(': + paren_count += 1 + elif char == ')': + paren_count -= 1 + elif char == '{': + brace_count += 1 + elif char == '}': + brace_count -= 1 + elif char == ',' and paren_count == 0 and brace_count == 0: + args.append(current_arg.strip()) + current_arg = "" + continue + + current_arg += char + + # Add the last argument + if current_arg.strip(): + args.append(current_arg.strip()) + + # We need at least 6 arguments to get DEP_EXTS (position 5) + if len(args) < 6: + return None + + ext_name = args[0].strip() + dep_exts_arg = args[5].strip() # DEP_EXTS is at position 5 + + # Parse dependency extensions from the DEP_EXTS argument + deps = parse_dep_exts(dep_exts_arg) + + return { + 'name': ext_name, + 'dep_exts': deps + } + +def parse_dep_exts(dep_exts_str): + """Parse the DEP_EXTS argument to extract dependency list with conditions.""" + # Remove outer parentheses if present + dep_exts_str = dep_exts_str.strip() + if dep_exts_str.startswith('(') and dep_exts_str.endswith(')'): + dep_exts_str = dep_exts_str[1:-1].strip() + + # Remove outer braces if present + if dep_exts_str.startswith('{') and dep_exts_str.endswith('}'): + dep_exts_str = dep_exts_str[1:-1].strip() + + if not dep_exts_str: + return [] + + deps = [] + + # First, find and process conditional dependencies + conditional_pattern = r'\{\s*"([^"]+)"\s*,\s*(\[.*?\]\s*\([^)]*\)\s*->\s*bool.*?)\}' + conditional_matches = [] + + for match in re.finditer(conditional_pattern, dep_exts_str, re.DOTALL): + ext_name = match.group(1) + condition_code = match.group(2) + deps.append({'ext': ext_name, 'type': 'conditional', 'condition': condition_code}) + conditional_matches.append((match.start(), match.end())) + + # Remove conditional dependency blocks from the string + remaining_str = dep_exts_str + for start, end in reversed(conditional_matches): # Reverse order to maintain indices + remaining_str = remaining_str[:start] + remaining_str[end:] + + # Now handle simple quoted strings in the remaining text + for match in re.finditer(r'"([^"]+)"', remaining_str): + deps.append({'ext': match.group(1), 'type': 'simple'}) + + # Remove duplicates while preserving order + seen = set() + unique_deps = [] + for dep in deps: + key = (dep['ext'], dep['type']) + if key not in seen: + seen.add(key) + unique_deps.append(dep) + + return unique_deps + +def evaluate_conditional_dependency(ext, dep, xlen, current_exts): + """Evaluate whether a conditional dependency should be included.""" + ext_name = dep['ext'] + condition = dep['condition'] + # Parse the condition based on known patterns + if ext_name == 'zcf' and ext in ['zca', 'c', 'zce']: + # zcf depends on RV32 and F extension + return xlen == 32 and 'f' in current_exts + elif ext_name == 'zcd' and ext in ['zca', 'c']: + # zcd depends on D extension + return 'd' in current_exts + elif ext_name == 'c' and ext in ['zca']: + # Special case for zca -> c conditional dependency + if xlen == 32: + if 'd' in current_exts: + return 'zcf' in current_exts and 'zcd' in current_exts + elif 'f' in current_exts: + return 'zcf' in current_exts + else: + return True + elif xlen == 64: + if 'd' in current_exts: + return 'zcd' in current_exts + else: + return True + return False + else: + # Report error for unhandled conditional dependencies + import sys + print(f"ERROR: Unhandled conditional dependency: '{ext_name}' with condition:", file=sys.stderr) + print(f" Condition code: {condition[:100]}...", file=sys.stderr) + print(f" Current context: xlen={xlen}, exts={sorted(current_exts)}", file=sys.stderr) + # For now, return False to be safe + return False + +def resolve_dependencies(arch_parts, xlen): + """Resolve all dependencies including conditional ones.""" + current_exts = set(arch_parts) + implied_deps = set() + + # Keep resolving until no new dependencies are found + changed = True + while changed: + changed = False + new_deps = set() + + for ext in current_exts | implied_deps: + if ext in IMPLIED_EXT: + for dep in IMPLIED_EXT[ext]: + if dep['type'] == 'simple': + if dep['ext'] not in current_exts and dep['ext'] not in implied_deps: + new_deps.add(dep['ext']) + changed = True + elif dep['type'] == 'conditional': + should_include = evaluate_conditional_dependency(ext, dep, xlen, current_exts | implied_deps) + if should_include: + if dep['ext'] not in current_exts and dep['ext'] not in implied_deps: + new_deps.add(dep['ext']) + changed = True + + implied_deps.update(new_deps) + + return implied_deps + +def parse_def_file(file_path, script_dir, processed_files=None, collect_all=False): + """Parse a single .def file and recursively process #include directives.""" + if processed_files is None: + processed_files = set() + + # Avoid infinite recursion + if file_path in processed_files: + return ({}, set()) if collect_all else {} + processed_files.add(file_path) + + implied_ext = {} + all_extensions = set() if collect_all else None + + if not os.path.exists(file_path): + return (implied_ext, all_extensions) if collect_all else implied_ext + + with open(file_path, 'r') as f: + content = f.read() + + # Process #include directives first + include_pattern = r'#include\s+"([^"]+)"' + includes = re.findall(include_pattern, content) + + for include_file in includes: + include_path = os.path.join(script_dir, include_file) + if collect_all: + included_ext, included_all = parse_def_file(include_path, script_dir, processed_files, collect_all) + implied_ext.update(included_ext) + all_extensions.update(included_all) + else: + included_ext = parse_def_file(include_path, script_dir, processed_files, collect_all) + implied_ext.update(included_ext) + + # Parse DEFINE_RISCV_EXT blocks using position-based parsing + parsed_exts = parse_define_riscv_ext(content) + + for ext_data in parsed_exts: + ext_name = ext_data['name'] + deps = ext_data['dep_exts'] + + if collect_all: + all_extensions.add(ext_name) + + if deps: + implied_ext[ext_name] = deps + + return (implied_ext, all_extensions) if collect_all else implied_ext + +def parse_def_files(): + """Parse RISC-V extension definition files starting from riscv-ext.def.""" + # Get directory containing this script + try: + script_dir = os.path.dirname(os.path.abspath(__file__)) + except NameError: + # When __file__ is not defined (e.g., interactive mode) + script_dir = os.getcwd() + + # Start with the main definition file + main_def_file = os.path.join(script_dir, 'riscv-ext.def') + return parse_def_file(main_def_file, script_dir) + +def get_all_extensions(): + """Get all supported extensions and their implied extensions.""" + # Get directory containing this script + try: + script_dir = os.path.dirname(os.path.abspath(__file__)) + except NameError: + # When __file__ is not defined (e.g., interactive mode) + script_dir = os.getcwd() + + # Start with the main definition file + main_def_file = os.path.join(script_dir, 'riscv-ext.def') + return parse_def_file(main_def_file, script_dir, collect_all=True) + # # IMPLIED_EXT(ext) -> implied extension list. +# This is loaded dynamically from .def files # -IMPLIED_EXT = { - "d" : ["f", "zicsr"], - - "a" : ["zaamo", "zalrsc"], - "zabha" : ["zaamo"], - "zacas" : ["zaamo"], - - "f" : ["zicsr"], - "b" : ["zba", "zbb", "zbs"], - "zdinx" : ["zfinx", "zicsr"], - "zfinx" : ["zicsr"], - "zhinx" : ["zhinxmin", "zfinx", "zicsr"], - "zhinxmin" : ["zfinx", "zicsr"], - - "zk" : ["zkn", "zkr", "zkt"], - "zkn" : ["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"], - "zks" : ["zbkb", "zbkc", "zbkx", "zksed", "zksh"], - - "v" : ["zvl128b", "zve64d"], - "zve32x" : ["zvl32b"], - "zve64x" : ["zve32x", "zvl64b"], - "zve32f" : ["f", "zve32x"], - "zve64f" : ["f", "zve32f", "zve64x"], - "zve64d" : ["d", "zve64f"], - - "zvl64b" : ["zvl32b"], - "zvl128b" : ["zvl64b"], - "zvl256b" : ["zvl128b"], - "zvl512b" : ["zvl256b"], - "zvl1024b" : ["zvl512b"], - "zvl2048b" : ["zvl1024b"], - "zvl4096b" : ["zvl2048b"], - "zvl8192b" : ["zvl4096b"], - "zvl16384b" : ["zvl8192b"], - "zvl32768b" : ["zvl16384b"], - "zvl65536b" : ["zvl32768b"], - - "zvkn" : ["zvkned", "zvknhb", "zvkb", "zvkt"], - "zvknc" : ["zvkn", "zvbc"], - "zvkng" : ["zvkn", "zvkg"], - "zvks" : ["zvksed", "zvksh", "zvkb", "zvkt"], - "zvksc" : ["zvks", "zvbc"], - "zvksg" : ["zvks", "zvkg"], - "zvbb" : ["zvkb"], - "zvbc" : ["zve64x"], - "zvkb" : ["zve32x"], - "zvkg" : ["zve32x"], - "zvkned" : ["zve32x"], - "zvknha" : ["zve32x"], - "zvknhb" : ["zve64x"], - "zvksed" : ["zve32x"], - "zvksh" : ["zve32x"], -} +IMPLIED_EXT = parse_def_files() def arch_canonicalize(arch, isa_spec): # TODO: Support extension version. @@ -123,21 +360,31 @@ def arch_canonicalize(arch, isa_spec): long_exts += extra_long_ext # - # Handle implied extensions. + # Handle implied extensions using new conditional logic. # - any_change = True - while any_change: - any_change = False - for ext in std_exts + long_exts: - if ext in IMPLIED_EXT: - implied_exts = IMPLIED_EXT[ext] - for implied_ext in implied_exts: - if implied_ext == 'zicsr' and is_isa_spec_2p2: - continue + # Extract xlen from architecture string + # TODO: We should support profile here. + if arch.startswith('rv32'): + xlen = 32 + elif arch.startswith('rv64'): + xlen = 64 + else: + raise Exception("Unsupported prefix `%s`" % arch) - if implied_ext not in std_exts + long_exts: - long_exts.append(implied_ext) - any_change = True + # Get all current extensions + current_exts = std_exts + long_exts + + # Resolve dependencies + implied_deps = resolve_dependencies(current_exts, xlen) + + # Filter out zicsr for ISA spec 2.2 + if is_isa_spec_2p2: + implied_deps.discard('zicsr') + + # Add implied dependencies to long_exts + for dep in implied_deps: + if dep not in current_exts: + long_exts.append(dep) # Single letter extension might appear in the long_exts list, # because we just append extensions list to the arch string. @@ -179,17 +426,171 @@ def arch_canonicalize(arch, isa_spec): return new_arch -if len(sys.argv) < 2: - print ("Usage: %s <arch_str> [<arch_str>*]" % sys.argv) - sys.exit(1) +def dump_all_extensions(): + """Dump all extensions and their implied extensions.""" + implied_ext, all_extensions = get_all_extensions() -parser = argparse.ArgumentParser() -parser.add_argument('-misa-spec', type=str, - default='20191213', - choices=SUPPORTED_ISA_SPEC) -parser.add_argument('arch_strs', nargs=argparse.REMAINDER) + print("All supported RISC-V extensions:") + print("=" * 60) -args = parser.parse_args() + if not all_extensions: + print("No extensions found.") + return -for arch in args.arch_strs: - print (arch_canonicalize(arch, args.misa_spec)) + # Sort all extensions for consistent output + sorted_all = sorted(all_extensions) + + # Print all extensions with their dependencies (if any) + for ext_name in sorted_all: + if ext_name in implied_ext: + deps = implied_ext[ext_name] + dep_strs = [] + for dep in deps: + if dep['type'] == 'simple': + dep_strs.append(dep['ext']) + else: + dep_strs.append(f"{dep['ext']}*") # Mark conditional deps with * + print(f"{ext_name:15} -> {', '.join(dep_strs)}") + else: + print(f"{ext_name:15} -> (no dependencies)") + + print(f"\nTotal extensions: {len(all_extensions)}") + print(f"Extensions with dependencies: {len(implied_ext)}") + print(f"Extensions without dependencies: {len(all_extensions) - len(implied_ext)}") + +def run_unit_tests(): + """Run unit tests using pytest dynamically imported.""" + try: + import pytest + except ImportError: + print("Error: pytest is required for running unit tests.") + print("Please install pytest: pip install pytest") + return 1 + + # Define test functions + def test_basic_arch_parsing(): + """Test basic architecture string parsing.""" + result = arch_canonicalize("rv64i", "20191213") + assert result == "rv64i" + + def test_simple_extensions(): + """Test simple extension handling.""" + result = arch_canonicalize("rv64im", "20191213") + assert "zmmul" in result + + def test_implied_extensions(): + """Test implied extension resolution.""" + result = arch_canonicalize("rv64imaf", "20191213") + assert "zicsr" in result + + def test_conditional_dependencies(): + """Test conditional dependency evaluation.""" + # Test RV32 with F extension should include zcf when c is present + result = arch_canonicalize("rv32ifc", "20191213") + parts = result.split("_") + if "c" in parts: + assert "zca" in parts + if "f" in parts: + assert "zcf" in parts + + def test_parse_dep_exts(): + """Test dependency parsing function.""" + # Test simple dependency + deps = parse_dep_exts('{"ext1", "ext2"}') + assert len(deps) == 2 + assert deps[0]['ext'] == 'ext1' + assert deps[0]['type'] == 'simple' + + def test_evaluate_conditional_dependency(): + """Test conditional dependency evaluation.""" + # Test zcf condition for RV32 with F + dep = {'ext': 'zcf', 'type': 'conditional', 'condition': 'test'} + result = evaluate_conditional_dependency('zce', dep, 32, {'f'}) + assert result == True + + # Test zcf condition for RV64 with F (should be False) + result = evaluate_conditional_dependency('zce', dep, 64, {'f'}) + assert result == False + + def test_parse_define_riscv_ext(): + """Test DEFINE_RISCV_EXT parsing.""" + content = ''' + DEFINE_RISCV_EXT( + /* NAME */ test, + /* UPPERCASE_NAME */ TEST, + /* FULL_NAME */ "Test extension", + /* DESC */ "", + /* URL */ , + /* DEP_EXTS */ ({"dep1", "dep2"}), + /* SUPPORTED_VERSIONS */ ({{1, 0}}), + /* FLAG_GROUP */ test, + /* BITMASK_GROUP_ID */ 0, + /* BITMASK_BIT_POSITION*/ 0, + /* EXTRA_EXTENSION_FLAGS */ 0) + ''' + + extensions = parse_define_riscv_ext(content) + assert len(extensions) == 1 + assert extensions[0]['name'] == 'test' + assert len(extensions[0]['dep_exts']) == 2 + + # Collect test functions + test_functions = [ + test_basic_arch_parsing, + test_simple_extensions, + test_implied_extensions, + test_conditional_dependencies, + test_parse_dep_exts, + test_evaluate_conditional_dependency, + test_parse_define_riscv_ext + ] + + # Run tests manually first, then optionally with pytest + print("Running unit tests...") + + passed = 0 + failed = 0 + + for i, test_func in enumerate(test_functions): + try: + print(f" Running {test_func.__name__}...", end=" ") + test_func() + print("PASSED") + passed += 1 + except Exception as e: + print(f"FAILED: {e}") + failed += 1 + + print(f"\nTest Summary: {passed} passed, {failed} failed") + + if failed == 0: + print("\nAll tests passed!") + return 0 + else: + print(f"\n{failed} test(s) failed!") + return 1 + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('-misa-spec', type=str, + default='20191213', + choices=SUPPORTED_ISA_SPEC) + parser.add_argument('--dump-all', action='store_true', + help='Dump all extensions and their implied extensions') + parser.add_argument('--selftest', action='store_true', + help='Run unit tests using pytest') + parser.add_argument('arch_strs', nargs='*', + help='Architecture strings to canonicalize') + + args = parser.parse_args() + + if args.dump_all: + dump_all_extensions() + elif args.selftest: + sys.exit(run_unit_tests()) + elif args.arch_strs: + for arch in args.arch_strs: + print (arch_canonicalize(arch, args.misa_spec)) + else: + parser.print_help() + sys.exit(1) diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 45fa521..29342d8 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -71,7 +71,7 @@ extern const char *riscv_arch_help (int argc, const char **argv); {"tune", "%{!mtune=*:" \ " %{!mcpu=*:-mtune=%(VALUE)}" \ " %{mcpu=*:-mtune=%:riscv_default_mtune(%* %(VALUE))}}" }, \ - {"arch", "%{!march=*:" \ + {"arch", "%{!march=*|march=unset:" \ " %{!mcpu=*:-march=%(VALUE)}" \ " %{mcpu=*:%:riscv_expand_arch_from_cpu(%* %(VALUE))}}" }, \ {"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \ @@ -111,13 +111,19 @@ extern const char *riscv_arch_help (int argc, const char **argv); %(subtarget_asm_spec)" \ ASM_MISA_SPEC +/* Drop all -march=* options before -march=unset. */ +#define ARCH_UNSET_CLEANUP_SPECS \ + "%{march=unset:%<march=*} " \ + #undef DRIVER_SELF_SPECS #define DRIVER_SELF_SPECS \ +ARCH_UNSET_CLEANUP_SPECS \ "%{march=help:%:riscv_arch_help()} " \ "%{print-supported-extensions:%:riscv_arch_help()} " \ "%{-print-supported-extensions:%:riscv_arch_help()} " \ "%{march=*:%:riscv_expand_arch(%*)} " \ -"%{!march=*:%{mcpu=*:%:riscv_expand_arch_from_cpu(%*)}} " +"%{!march=*|march=unset:%{mcpu=*:%:riscv_expand_arch_from_cpu(%*)}} " \ +"%{march=unset:%{!mcpu=*:%eAt least one valid -mcpu option must be given after -march=unset}} " #define LOCAL_LABEL_PREFIX "." #define USER_LABEL_PREFIX "" 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 3ab14f0..8e9b8ea 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,37 @@ +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 + * constexpr.cc (cxx_eval_store_expression): Handle clobbers. + (potential_constant_expression_1): Handle clobbers more. + * decl.cc (build_clobber_this): Use INIT_EXPR for initial clobber. + * init.cc (build_new_1): Clobber on placement new. + (build_vec_init): Don't clean up after clobber. + 2025-08-04 Patrick Palka <ppalka@redhat.com> PR c++/121351 diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 142579a..b8ac454 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -7179,10 +7179,23 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t))); /* DR 1188 says we don't have to deal with this. */ if (!ctx->quiet) - error_at (cp_expr_loc_or_input_loc (t), - "accessing value of %qE through a %qT glvalue in a " - "constant expression", build_fold_indirect_ref (sub), - TREE_TYPE (t)); + { + auto_diagnostic_group d; + error_at (cp_expr_loc_or_input_loc (t), + "accessing value of %qT object through a %qT " + "glvalue in a constant expression", + TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)); + tree ob = build_fold_indirect_ref (sub); + if (DECL_P (ob)) + { + if (DECL_ARTIFICIAL (ob)) + inform (DECL_SOURCE_LOCATION (ob), + "%qT object created here", TREE_TYPE (ob)); + else + inform (DECL_SOURCE_LOCATION (ob), + "%q#D declared here", ob); + } + } *non_constant_p = true; return t; } @@ -7452,12 +7465,6 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, tree init = TREE_OPERAND (t, 1); - if (TREE_CLOBBER_P (init) - && CLOBBER_KIND (init) < CLOBBER_OBJECT_END) - /* Only handle clobbers ending the lifetime of objects. - ??? We should probably set CONSTRUCTOR_NO_CLEARING. */ - return void_node; - /* First we figure out where we're storing to. */ tree target = TREE_OPERAND (t, 0); @@ -7644,11 +7651,14 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, } /* Handle explicit end-of-lifetime. */ - if (TREE_CLOBBER_P (init)) + if (TREE_CLOBBER_P (init) + && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END) { if (refs->is_empty ()) - ctx->global->destroy_value (object); - return void_node; + { + ctx->global->destroy_value (object); + return void_node; + } } type = TREE_TYPE (object); @@ -7785,6 +7795,8 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, *non_constant_p = true; } else if (!is_access_expr + || (TREE_CLOBBER_P (init) + && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END) || (TREE_CODE (t) == MODIFY_EXPR && CLASS_TYPE_P (inner) && !type_has_non_deleted_trivial_default_ctor (inner))) @@ -7848,11 +7860,17 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, type = reftype; } + /* Change an "as-base" clobber to the real type; + we don't need to worry about padding in constexpr. */ + tree itype = initialized_type (init); + if (IS_FAKE_BASE_TYPE (itype)) + itype = TYPE_CONTEXT (itype); + /* For initialization of an empty base, the original target will be *(base*)this, evaluation of which resolves to the object argument, which has the derived type rather than the base type. */ if (!empty_base && !(same_type_ignoring_top_level_qualifiers_p - (initialized_type (init), type))) + (itype, type))) { gcc_assert (is_empty_class (TREE_TYPE (target))); empty_base = true; @@ -7959,8 +7977,10 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, /* Don't share a CONSTRUCTOR that might be changed later. */ init = unshare_constructor (init); - gcc_checking_assert (!*valp || (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (*valp), type))); + gcc_checking_assert (!*valp + || *valp == void_node + || (same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (*valp), type))); if (empty_base) { /* Just evaluate the initializer and return, since there's no actual data @@ -7973,6 +7993,22 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits; } } + else if (TREE_CLOBBER_P (init)) + { + if (AGGREGATE_TYPE_P (type)) + { + if (*valp) + CONSTRUCTOR_ELTS (*valp) = nullptr; + else + *valp = build_constructor (type, nullptr); + TREE_CONSTANT (*valp) = true; + TREE_SIDE_EFFECTS (*valp) = false; + CONSTRUCTOR_NO_CLEARING (*valp) = true; + CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits; + } + else + *valp = void_node; + } else if (*valp && TREE_CODE (*valp) == CONSTRUCTOR && TREE_CODE (init) == CONSTRUCTOR) { @@ -7997,6 +8033,9 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, && TREE_CODE (*valp) == CONSTRUCTOR && TYPE_READONLY (type)) { + tree target_type = TREE_TYPE (target); + if (IS_FAKE_BASE_TYPE (target_type)) + target_type = TYPE_CONTEXT (target_type); if (INDIRECT_REF_P (target) && (is_this_parameter (tree_strip_nop_conversions (TREE_OPERAND (target, 0))))) @@ -8004,7 +8043,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, constructor of a delegating constructor). Leave it up to the caller that set 'this' to set TREE_READONLY appropriately. */ gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (target), type) || empty_base); + (target_type, type) || empty_base); else TREE_READONLY (*valp) = true; } @@ -11308,6 +11347,13 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t)) && !NULLPTR_TYPE_P (TREE_TYPE (t))) { + if (TREE_CLOBBER_P (t)) + { + /* We should have caught any clobbers in INIT/MODIFY_EXPR. */ + gcc_checking_assert (false); + return true; + } + if (flags & tf_error) constexpr_error (loc, fundef_p, "lvalue-to-rvalue conversion of " "a volatile lvalue %qE with type %qT", t, @@ -12131,6 +12177,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, } /* FALLTHRU */ case INIT_EXPR: + if (TREE_CLOBBER_P (TREE_OPERAND (t, 1))) + return true; return RECUR (TREE_OPERAND (t, 1), rval); case CONSTRUCTOR: diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index cb3ebff..8122fca 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -18440,6 +18440,8 @@ build_clobber_this (clobber_kind kind) } tree exprstmt = build2 (MODIFY_EXPR, void_type_node, thisref, clobber); + if (kind == CLOBBER_OBJECT_BEGIN) + TREE_SET_CODE (exprstmt, INIT_EXPR); if (vbases) exprstmt = build_if_in_charge (exprstmt); diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 09fb4f3..f19794c 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -3557,9 +3557,19 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, alloc_expr = maybe_wrap_new_for_constexpr (alloc_expr, type, cookie_size); + bool std_placement = std_placement_new_fn_p (alloc_fn); + + /* For std placement new, clobber the object if the constructor won't do it + in start_preparsed_function. This is most important for activating an + array in a union (c++/121068), but should also help the optimizers. */ + const bool do_clobber + = (std_placement && !*init && flag_lifetime_dse > 1 + && (!CLASS_TYPE_P (elt_type) + || type_has_non_user_provided_default_constructor (elt_type))); + /* In the simple case, we can stop now. */ pointer_type = build_pointer_type (type); - if (!cookie_size && !is_initialized && !member_delete_p) + if (!cookie_size && !is_initialized && !member_delete_p && !do_clobber) return build_nop (pointer_type, alloc_expr); /* Store the result of the allocation call in a variable so that we can @@ -3593,8 +3603,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, So check for a null exception spec on the op new we just called. */ nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn)); - check_new - = flag_check_new || (nothrow && !std_placement_new_fn_p (alloc_fn)); + check_new = flag_check_new || (nothrow && !std_placement); if (cookie_size) { @@ -3649,6 +3658,29 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, /* Any further uses of alloc_node will want this type, too. */ alloc_node = fold_convert (non_const_pointer_type, alloc_node); + tree clobber_expr = NULL_TREE; + if (do_clobber) + { + tree clobber = build_clobber (elt_type, CLOBBER_OBJECT_BEGIN); + CONSTRUCTOR_IS_DIRECT_INIT (clobber) = true; + if (array_p) + { + /* Clobber each element rather than the array at once. */ + tree maxindex = cp_build_binary_op (input_location, + MINUS_EXPR, outer_nelts, + integer_one_node, + complain); + clobber_expr = build_vec_init (data_addr, maxindex, clobber, + /*valinit*/false, /*from_arr*/0, + complain, nullptr); + } + else + { + tree targ = cp_build_fold_indirect_ref (data_addr); + clobber_expr = cp_build_init_expr (targ, clobber); + } + } + /* Now initialize the allocated object. Note that we preevaluate the initialization expression, apart from the actual constructor call or assignment--we do this because we want to delay the allocation as long @@ -3877,6 +3909,8 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, if (init_expr) rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_expr, rval); + if (clobber_expr) + rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), clobber_expr, rval); if (cookie_expr) rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval); @@ -4717,6 +4751,9 @@ build_vec_init (tree base, tree maxindex, tree init, the partially constructed array if an exception is thrown. But don't do this if we're assigning. */ if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) + /* And don't clean up from clobbers, the actual initialization will + follow as a separate build_vec_init. */ + && !(init && TREE_CLOBBER_P (init)) && from_array != 2) { tree e; diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 13d5ded..fd69099 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -3745,11 +3745,59 @@ write_expression (tree expr) || !zero_init_expr_p (ce->value)) last_nonzero = i; + tree prev_field = NULL_TREE; if (undigested || last_nonzero != UINT_MAX) for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i) { if (i > last_nonzero) break; + if (!undigested && !CONSTRUCTOR_NO_CLEARING (expr) + && (TREE_CODE (etype) == RECORD_TYPE + || TREE_CODE (etype) == ARRAY_TYPE)) + { + /* Write out any implicit non-trailing zeros + (which we neglected to do before v21). */ + if (TREE_CODE (etype) == RECORD_TYPE) + { + tree field; + if (i == 0) + field = first_field (etype); + else + field = DECL_CHAIN (prev_field); + for (;;) + { + field = next_subobject_field (field); + if (field == ce->index) + break; + if (abi_check (21)) + write_expression (build_zero_cst + (TREE_TYPE (field))); + field = DECL_CHAIN (field); + } + } + else if (TREE_CODE (etype) == ARRAY_TYPE) + { + unsigned HOST_WIDE_INT j; + if (i == 0) + j = 0; + else + j = 1 + tree_to_uhwi (prev_field); + unsigned HOST_WIDE_INT k; + if (TREE_CODE (ce->index) == RANGE_EXPR) + k = tree_to_uhwi (TREE_OPERAND (ce->index, 0)); + else + k = tree_to_uhwi (ce->index); + tree zero = NULL_TREE; + for (; j < k; ++j) + if (abi_check (21)) + { + if (!zero) + zero = build_zero_cst (TREE_TYPE (etype)); + write_expression (zero); + } + } + } + if (!undigested && TREE_CODE (etype) == UNION_TYPE) { /* Express the active member as a designator. */ @@ -3794,6 +3842,9 @@ write_expression (tree expr) else for (unsigned j = 0; j < reps; ++j) write_expression (ce->value); + prev_field = ce->index; + if (prev_field && TREE_CODE (prev_field) == RANGE_EXPR) + prev_field = TREE_OPERAND (prev_field, 1); } } else diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 860f3f0..a8c54c7 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -42636,8 +42636,11 @@ cp_parser_omp_clause_doacross (cp_parser *parser, tree list, location_t loc) to ( variable-list ) OpenMP 5.1: - from ( [present :] variable-list ) - to ( [present :] variable-list ) */ + from ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list ) + to ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list ) + + motion-modifier: + present | iterator (iterators-definition) */ static tree cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind, @@ -42646,23 +42649,113 @@ cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind, if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return list; - bool present = false; - cp_token *token = cp_lexer_peek_token (parser->lexer); + int pos = 1; + int colon_pos = 0; + int iterator_length = 0; - if (token->type == CPP_NAME - && strcmp (IDENTIFIER_POINTER (token->u.value), "present") == 0 - && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON)) + while (cp_lexer_peek_nth_token (parser->lexer, pos)->type == CPP_NAME) { - present = true; - cp_lexer_consume_token (parser->lexer); - cp_lexer_consume_token (parser->lexer); + const char *identifier = + IDENTIFIER_POINTER (cp_lexer_peek_nth_token (parser->lexer, + pos)->u.value); + if (cp_lexer_nth_token_is (parser->lexer, pos + 1, CPP_OPEN_PAREN)) + { + int n = cp_parser_skip_balanced_tokens (parser, pos + 1); + if (n != pos + 1) + { + if (strcmp (identifier, "iterator") == 0) + iterator_length = n - pos; + pos = n - 1; + } + } + if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COMMA) + pos += 2; + else + pos++; + if (cp_lexer_peek_nth_token (parser->lexer, pos)->type == CPP_COLON) + { + colon_pos = pos; + break; + } } + bool present = false; + tree iterators = NULL_TREE; + + for (int pos = 1; pos < colon_pos; ++pos) + { + cp_token *token = cp_lexer_peek_token (parser->lexer); + if (token->type == CPP_COMMA) + { + cp_lexer_consume_token (parser->lexer); + continue; + } + const char *p = IDENTIFIER_POINTER (token->u.value); + if (strcmp ("present", p) == 0) + { + if (present) + { + cp_parser_error (parser, "too many %<present%> modifiers"); + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + present = true; + cp_lexer_consume_token (parser->lexer); + } + else if (strcmp ("iterator", p) == 0) + { + if (iterators) + { + cp_parser_error (parser, "too many %<iterator%> modifiers"); + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + begin_scope (sk_omp, NULL); + iterators = cp_parser_omp_iterators (parser); + pos += iterator_length - 1; + } + + else + { + error_at (token->location, + "%qs clause with modifier other than %<iterator%> " + "or %<present%>", + kind == OMP_CLAUSE_TO ? "to" : "from"); + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + } + + if (colon_pos) + cp_parser_require (parser, CPP_COLON, RT_COLON); + tree nl = cp_parser_omp_var_list_no_open (parser, kind, list, NULL, true); if (present) for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) OMP_CLAUSE_MOTION_PRESENT (c) = 1; + if (iterators) + { + tree block = poplevel (1, 1, 0); + if (iterators == error_mark_node) + iterators = NULL_TREE; + else + TREE_VEC_ELT (iterators, 5) = block; + } + + if (iterators) + for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) + OMP_CLAUSE_ITERATORS (c) = iterators; + return nl; } @@ -42696,16 +42789,34 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list, bool declare_mapper_p) int pos = 1; int map_kind_pos = 0; - while (cp_lexer_peek_nth_token (parser->lexer, pos)->type == CPP_NAME - || cp_lexer_peek_nth_token (parser->lexer, pos)->keyword == RID_DELETE) + int iterator_length = 0; + for (;;) { - if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COLON) + cp_token *tok = cp_lexer_peek_nth_token (parser->lexer, pos); + if (!(tok->type == CPP_NAME || tok->keyword == RID_DELETE)) + break; + + cp_token *next_tok = cp_lexer_peek_nth_token (parser->lexer, pos + 1); + if (tok->type == CPP_NAME + && strcmp (IDENTIFIER_POINTER (tok->u.value), "iterator") == 0 + && next_tok->type == CPP_OPEN_PAREN) + { + int n = cp_parser_skip_balanced_tokens (parser, pos + 1); + if (n != pos + 1) + { + iterator_length = n - pos; + pos = n - 1; + next_tok = cp_lexer_peek_nth_token (parser->lexer, n); + } + } + + if (next_tok->type == CPP_COLON) { map_kind_pos = pos; break; } - if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COMMA) + if (next_tok->type == CPP_COMMA) pos++; else if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_OPEN_PAREN) @@ -42718,6 +42829,7 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list, bool declare_mapper_p) bool present_modifier = false; bool mapper_modifier = false; tree mapper_name = NULL_TREE; + tree iterators = NULL_TREE; for (int pos = 1; pos < map_kind_pos; ++pos) { cp_token *tok = cp_lexer_peek_token (parser->lexer); @@ -42756,6 +42868,21 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list, bool declare_mapper_p) close_modifier = true; cp_lexer_consume_token (parser->lexer); } + else if (strcmp ("iterator", p) == 0) + { + if (iterators) + { + cp_parser_error (parser, "too many %<iterator%> modifiers"); + cp_parser_skip_to_closing_parenthesis (parser, + /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + begin_scope (sk_omp, NULL); + iterators = cp_parser_omp_iterators (parser); + pos += iterator_length - 1; + } else if (strcmp ("mapper", p) == 0) { cp_lexer_consume_token (parser->lexer); @@ -42844,7 +42971,7 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list, bool declare_mapper_p) { cp_parser_error (parser, "%<map%> clause with map-type modifier " "other than %<always%>, %<close%>, " - "%<mapper%> or %<present%>"); + "%<iterator%>, %<mapper%> or %<present%>"); cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, @@ -42908,9 +43035,19 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list, bool declare_mapper_p) tree last_new = NULL_TREE; + if (iterators) + { + tree block = poplevel (1, 1, 0); + if (iterators == error_mark_node) + iterators = NULL_TREE; + else + TREE_VEC_ELT (iterators, 5) = block; + } + for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) { OMP_CLAUSE_SET_MAP_KIND (c, kind); + OMP_CLAUSE_ITERATORS (c) = iterators; last_new = c; } diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index be79b50..0c7788d 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -7751,7 +7751,14 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* We've reached the end of a list of expanded nodes. Reset the group start pointer. */ if (c == grp_sentinel) - grp_start_p = NULL; + { + if (grp_start_p + && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p)) + for (tree gc = *grp_start_p; gc != grp_sentinel; + gc = OMP_CLAUSE_CHAIN (gc)) + OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p); + grp_start_p = NULL; + } switch (OMP_CLAUSE_CODE (c)) { @@ -9003,6 +9010,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) /* FALLTHRU */ case OMP_CLAUSE_TO: case OMP_CLAUSE_FROM: + if (OMP_CLAUSE_ITERATORS (c) + && cp_omp_finish_iterators (OMP_CLAUSE_ITERATORS (c))) + { + t = error_mark_node; + break; + } + /* FALLTHRU */ case OMP_CLAUSE__CACHE_: { using namespace omp_addr_tokenizer; @@ -9906,6 +9920,11 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) pc = &OMP_CLAUSE_CHAIN (c); } + if (grp_start_p + && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p)) + for (tree gc = *grp_start_p; gc; gc = OMP_CLAUSE_CHAIN (gc)) + OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p); + if (reduction_seen < 0 && (ordered_seen || schedule_seen)) reduction_seen = -2; 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 105a60d..00468a7 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3016,8 +3016,9 @@ Version 20, which first appeared in G++ 15, fixes manglings of lambdas in static data member initializers. Version 21, which first appeared in G++ 16, fixes unnecessary captures -in noexcept lambdas (c++/119764) and layout of a base class -with all explicitly defaulted constructors (c++/120012). +in noexcept lambdas (c++/119764), layout of a base class with all explicitly +defaulted constructors (c++/120012), and mangling of class and array +objects with implicitly zero-initialized non-trailing subobjects (c++/121231). See also @option{-Wabi}. @@ -31336,7 +31337,7 @@ The default is @option{-misa-spec=20191213} unless GCC has been configured with @option{--with-isa-spec=} specifying a different default version. @opindex march -@item -march=@var{ISA-string|Profiles|Profile_ISA-string} +@item -march=@var{ISA-string|Profiles|Profile_ISA-string|help|unset} Generate code for given RISC-V ISA or Profiles or a combination of them (e.g.@: @samp{rv64im} @samp{rvi20u64} @samp{rvi20u64_zbb}). ISA strings and Profiles must be lower-case. Examples include @samp{rv64i}, @samp{rv32g}, @@ -31347,6 +31348,12 @@ at the beginning of the option, then use underline connect ISA-string (e.g.@: @option{help} (@option{-march=help}) is accepted to list all supported extensions. +@samp{-march=unset} causes the compiler to ignore any @samp{-march=@dots{}} options +that appear earlier on the command line, behaving as if the option was never +passed. This is useful for ensuring that the architecture is taken from the +@samp{-mcpu} option, and it will result in an error if no @samp{-mcpu} option +is given when @samp{-march=unset} is used. + The syntax of the ISA string is defined as follows: @table @code diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d75d64f..20e4a76 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,68 @@ +2025-08-05 Mikael Morin <morin-mikael@orange.fr> + + * trans-stmt.cc (trans_associate_var): Remove overwrite of + the polymorphic associate variable's array descriptor offset. + +2025-08-05 Mikael Morin <morin-mikael@orange.fr> + + * trans-array.cc (trans_array_constructor): Remove the update of + the array descriptor upper bound after array constructor + expansion. + +2025-08-05 Mikael Morin <morin-mikael@orange.fr> + + * trans-array.cc (gfc_conv_expr_descriptor): Remove + isolated initialization of the span field before passing to + the function that will do the initialization. + +2025-08-05 Mikael Morin <morin-mikael@orange.fr> + + * trans-decl.cc (gfc_trans_deferred_vars): Don't default + initialize the span of local pointer arrays. + +2025-08-05 Mikael Morin <morin-mikael@orange.fr> + + * trans-stmt.cc (trans_associate_var): Remove overwrite of the + span field of the associate variable's array descriptor. + +2025-08-05 Mikael Morin <morin-mikael@orange.fr> + + * trans-expr.cc (gfc_trans_pointer_assignment): Remove overwrite + of the span after assignment of the array descriptor in the + polymorphic function result to non-polymorphic pointer case. + +2025-08-05 Mikael Morin <mikael@gcc.gnu.org> + + * trans.h (gfc_se): Remove field use_offset. + * trans-expr.cc (gfc_conv_intrinsic_to_class): Remove use_offset + initialization. + (gfc_conv_procedure_call): Likewise. + * trans-stmt.cc (trans_associate_var): Likewise. + +2025-08-05 Mikael Morin <mikael@gcc.gnu.org> + + * trans-array.cc (gfc_alloc_allocatable_for_assignment): Use the + offset setter instead of generating a write to the offset. + (gfc_conv_array_parameter): Use the offset setter instead of + generating a write to the value returned by the offset getter. + * trans-expr.cc (gfc_trans_alloc_subarray_assign): Likewise. + +2025-08-05 Mikael Morin <mikael@gcc.gnu.org> + + * trans-array.cc (gfc_conv_descriptor_data_addr): Remove. + * trans-array.h (gfc_conv_descriptor_data_addr): Remove. + * trans-decl.cc (gfc_trans_deferred_vars): Use + gfc_conv_descriptor_data_get. + +2025-08-05 Mikael Morin <mikael@gcc.gnu.org> + + * trans.cc (gfc_finalize_tree_expr): Use the data setter instead + of writing to the value returned by the data getter. + * trans-decl.cc (gfc_trans_deferred_vars): Likewise. + * trans-stmt.cc (trans_associate_var): Use the data setter + instead of writing to the value dereferenced from the data + address. + 2025-08-01 Mikael Morin <mikael@gcc.gnu.org> * trans-decl.cc (gfc_trans_deferred_vars): Fix closing brace in diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc index 5974e40..f4e6c57 100644 --- a/gcc/fortran/trans-stmt.cc +++ b/gcc/fortran/trans-stmt.cc @@ -1876,9 +1876,6 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) bool class_target; bool unlimited; tree desc; - tree offset; - tree dim; - int n; tree charlen; bool need_len_assign; bool whole_array = true; @@ -2292,21 +2289,6 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block) desc = gfc_class_data_get (se.expr); - /* Set the offset. */ - offset = gfc_index_zero_node; - for (n = 0; n < e->rank; n++) - { - dim = gfc_rank_cst[n]; - tmp = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, - gfc_conv_descriptor_stride_get (desc, dim), - gfc_conv_descriptor_lbound_get (desc, dim)); - offset = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, - offset, tmp); - } - gfc_conv_descriptor_offset_set (&se.pre, desc, offset); - if (need_len_assign) { if (e->symtree diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l index e36ca5b..37e4eb0 100644 --- a/gcc/gengtype-lex.l +++ b/gcc/gengtype-lex.l @@ -21,17 +21,6 @@ along with GCC; see the file COPYING3. If not see %option noinput %{ -#ifdef HOST_GENERATOR_FILE -#include "config.h" -#define GENERATOR_FILE 1 -#else -#include "bconfig.h" -#endif -#include "system.h" - -#define malloc xmalloc -#define realloc xrealloc - #include "gengtype.h" #define YY_DECL int yylex (const char **yylval) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 8fb7a60..1e434ce 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -76,7 +76,7 @@ enum bitint_prec_kind { /* Caches to speed up bitint_precision_kind. */ static int small_max_prec, mid_min_prec, large_min_prec, huge_min_prec; -static int limb_prec; +static int limb_prec, abi_limb_prec; static bool bitint_big_endian, bitint_extended; /* Categorize _BitInt(PREC) as small, middle, large or huge. */ @@ -109,6 +109,9 @@ bitint_precision_kind (int prec) large_min_prec = MAX_FIXED_MODE_SIZE + 1; if (!limb_prec) limb_prec = GET_MODE_PRECISION (limb_mode); + if (!abi_limb_prec) + abi_limb_prec + = GET_MODE_PRECISION (as_a <scalar_int_mode> (info.abi_limb_mode)); if (!huge_min_prec) { if (4 * limb_prec >= MAX_FIXED_MODE_SIZE) @@ -429,7 +432,7 @@ struct bitint_large_huge void insert_before (gimple *); tree limb_access_type (tree, tree); - tree limb_access (tree, tree, tree, bool); + tree limb_access (tree, tree, tree, bool, bool = false); tree build_bit_field_ref (tree, tree, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT); void if_then (gimple *, profile_probability, edge &, edge &); @@ -610,11 +613,14 @@ bitint_large_huge::limb_access_type (tree type, tree idx) TYPE. If WRITE_P is true, it will be a store, otherwise a read. */ tree -bitint_large_huge::limb_access (tree type, tree var, tree idx, bool write_p) +bitint_large_huge::limb_access (tree type, tree var, tree idx, bool write_p, + bool abi_load_p) { tree atype = (tree_fits_uhwi_p (idx) ? limb_access_type (type, idx) : m_limb_type); - tree ltype = m_limb_type; + + tree ltype = (bitint_extended && abi_load_p) ? atype : m_limb_type; + addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (var)); if (as != TYPE_ADDR_SPACE (ltype)) ltype = build_qualified_type (ltype, TYPE_QUALS (ltype) @@ -651,12 +657,21 @@ bitint_large_huge::limb_access (tree type, tree var, tree idx, bool write_p) { unsigned HOST_WIDE_INT nelts = CEIL (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var))), limb_prec); - tree atype = build_array_type_nelts (ltype, nelts); + + /* Build the array type with m_limb_type from the right address + space. */ + tree limb_type_a = m_limb_type; + if (as != TYPE_ADDR_SPACE (m_limb_type)) + limb_type_a = build_qualified_type (m_limb_type, + TYPE_QUALS (m_limb_type) + | ENCODE_QUAL_ADDR_SPACE (as)); + + tree atype = build_array_type_nelts (limb_type_a, nelts); var = build1 (VIEW_CONVERT_EXPR, atype, var); } ret = build4 (ARRAY_REF, ltype, var, idx, NULL_TREE, NULL_TREE); } - if (!write_p && !useless_type_conversion_p (atype, m_limb_type)) + if (!write_p && !useless_type_conversion_p (atype, ltype)) { gimple *g = gimple_build_assign (make_ssa_name (m_limb_type), ret); insert_before (g); @@ -1964,6 +1979,7 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx) tree rhs1 = gimple_assign_rhs1 (stmt); tree rhs_type = TREE_TYPE (rhs1); bool eh = stmt_ends_bb_p (stmt); + bool load_bitfield_p = false; edge eh_edge = NULL; gimple *g; @@ -1987,12 +2003,18 @@ bitint_large_huge::handle_load (gimple *stmt, tree idx) if (!bitint_big_endian && DECL_OFFSET_ALIGN (fld) >= TYPE_ALIGN (TREE_TYPE (rhs1)) && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)) % limb_prec) == 0) - goto normal_load; + { + load_bitfield_p = true; + goto normal_load; + } /* Even if DECL_FIELD_BIT_OFFSET (fld) is a multiple of BITS_PER_UNIT, handle it normally for now. */ if (!bitint_big_endian && (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)) % BITS_PER_UNIT) == 0) - goto normal_load; + { + load_bitfield_p = true; + goto normal_load; + } tree repr = DECL_BIT_FIELD_REPRESENTATIVE (fld); poly_int64 bitoffset; poly_uint64 field_offset, repr_offset; @@ -2241,7 +2263,7 @@ normal_load: /* Use write_p = true for loads with EH edges to make sure limb_access doesn't add a cast as separate statement after it. */ - rhs1 = limb_access (rhs_type, rhs1, idx, eh); + rhs1 = limb_access (rhs_type, rhs1, idx, eh, !load_bitfield_p); tree ret = make_ssa_name (TREE_TYPE (rhs1)); g = gimple_build_assign (ret, rhs1); insert_before (g); @@ -2373,7 +2395,7 @@ range_to_prec (tree op, gimple *stmt) from that precision, if it is negative, the operand is sign-extended from -*PREC. If PREC_STORED is NULL, it is the toplevel call, otherwise *PREC_STORED is prec from the innermost call without - range optimizations. */ + range optimizations (0 for uninitialized SSA_NAME). */ tree bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, @@ -2481,7 +2503,7 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, *prec = TYPE_UNSIGNED (TREE_TYPE (op)) ? limb_prec : -limb_prec; precs = *prec; if (prec_stored) - *prec_stored = precs; + *prec_stored = 0; tree var = create_tmp_var (m_limb_type); TREE_ADDRESSABLE (var) = 1; ret = build_fold_addr_expr (var); @@ -2510,6 +2532,13 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, int prec_stored_val = 0; ret = handle_operand_addr (rhs1, g, &prec_stored_val, prec); precs = prec_stored_val; + if (prec_stored) + *prec_stored = prec_stored_val; + if (precs == 0) + { + gcc_assert (*prec == limb_prec || *prec == -limb_prec); + precs = *prec; + } if (TYPE_PRECISION (lhs_type) > TYPE_PRECISION (rhs_type)) { if (TYPE_UNSIGNED (lhs_type) @@ -2518,7 +2547,9 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, } else { - if (*prec > 0 && *prec < TYPE_PRECISION (lhs_type)) + if (prec_stored_val == 0) + /* Non-widening cast of uninitialized value. */; + else if (*prec > 0 && *prec < TYPE_PRECISION (lhs_type)) ; else if (TYPE_UNSIGNED (lhs_type)) { @@ -3150,6 +3181,17 @@ bitint_large_huge::lower_mergeable_stmt (gimple *stmt, tree_code &cmp_code, { tree l = limb_access (nlhs ? NULL_TREE : lhs_type, nlhs ? nlhs : lhs, idx, true); + + if (bitint_extended + && sext + && TYPE_UNSIGNED (lhs_type) + && tree_fits_uhwi_p (idx) + && !nlhs) + { + rhs1 = add_cast (limb_access_type (lhs_type, idx), rhs1); + rhs1 = add_cast (TREE_TYPE (l), rhs1); + } + g = gimple_build_assign (l, rhs1); } insert_before (g); @@ -6669,7 +6711,7 @@ static unsigned int gimple_lower_bitint (void) { small_max_prec = mid_min_prec = large_min_prec = huge_min_prec = 0; - limb_prec = 0; + limb_prec = abi_limb_prec = 0; bitint_big_endian = false; unsigned int i; @@ -7631,7 +7673,20 @@ gimple_lower_bitint (void) from smaller number. */ min_prec = prec; else - min_prec = CEIL (min_prec, limb_prec) * limb_prec; + { + min_prec = CEIL (min_prec, limb_prec) * limb_prec; + if (min_prec > (unsigned) limb_prec + && abi_limb_prec > limb_prec) + { + /* For targets with ABI limb precision higher than + limb precision round to ABI limb precision, + otherwise c can contain padding bits. */ + min_prec + = CEIL (min_prec, abi_limb_prec) * abi_limb_prec; + if (min_prec > prec - rem - 2 * limb_prec) + min_prec = prec; + } + } if (min_prec == 0) c = NULL_TREE; else if (min_prec == prec) diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc index 4e20b4c..6929cd0 100644 --- a/gcc/gimple-pretty-print.cc +++ b/gcc/gimple-pretty-print.cc @@ -1837,6 +1837,12 @@ dump_gimple_omp_target (pretty_printer *pp, const gomp_target *gs, default: gcc_unreachable (); } + if (gimple_omp_target_iterator_loops (gs)) + { + pp_string (pp, "// Expanded iterator loops for #pragma omp target\n"); + dump_gimple_seq (pp, gimple_omp_target_iterator_loops (gs), spc, flags); + pp_newline (pp); + } if (flags & TDF_RAW) { dump_gimple_fmt (pp, spc, flags, "%G%s <%+BODY <%S>%nCLAUSES <", gs, diff --git a/gcc/gimple.cc b/gcc/gimple.cc index 41908d4..102e21f 100644 --- a/gcc/gimple.cc +++ b/gcc/gimple.cc @@ -1295,10 +1295,13 @@ gimple_build_omp_interop (tree clauses) BODY is the sequence of statements that will be executed. KIND is the kind of the region. - CLAUSES are any of the construct's clauses. */ + CLAUSES are any of the construct's clauses. + ITERATOR_LOOPS is an optional sequence containing constructed loops + for OpenMP iterators. */ gomp_target * -gimple_build_omp_target (gimple_seq body, int kind, tree clauses) +gimple_build_omp_target (gimple_seq body, int kind, tree clauses, + gimple_seq iterator_loops) { gomp_target *p = as_a <gomp_target *> (gimple_alloc (GIMPLE_OMP_TARGET, 0)); @@ -1306,6 +1309,7 @@ gimple_build_omp_target (gimple_seq body, int kind, tree clauses) gimple_omp_set_body (p, body); gimple_omp_target_set_clauses (p, clauses); gimple_omp_target_set_kind (p, kind); + gimple_omp_target_set_iterator_loops (p, iterator_loops); return p; } diff --git a/gcc/gimple.def b/gcc/gimple.def index 54248a8..3e1e13e 100644 --- a/gcc/gimple.def +++ b/gcc/gimple.def @@ -393,7 +393,7 @@ DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE_LAYOUT) DATA_ARG is a vec of 3 local variables in the parent function containing data to be mapped to CHILD_FN. This is used to implement the MAP clauses. */ -DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_PARALLEL_LAYOUT) +DEFGSCODE(GIMPLE_OMP_TARGET, "gimple_omp_target", GSS_OMP_TARGET) /* GIMPLE_OMP_TEAMS <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents #pragma omp teams diff --git a/gcc/gimple.h b/gcc/gimple.h index 5c970ce..da32651 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -682,11 +682,14 @@ struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) }; /* GIMPLE_OMP_TARGET */ -struct GTY((tag("GSS_OMP_PARALLEL_LAYOUT"))) +struct GTY((tag("GSS_OMP_TARGET"))) gomp_target : public gimple_statement_omp_parallel_layout { - /* No extra fields; adds invariant: - stmt->code == GIMPLE_OMP_TARGET. */ + /* [ WORD 1-10 ] : base class */ + + /* [ WORD 11 ] + Iterator loops. */ + gimple_seq iterator_loops; }; /* GIMPLE_OMP_TASK */ @@ -1607,7 +1610,7 @@ gomp_scan *gimple_build_omp_scan (gimple_seq, tree); gomp_sections *gimple_build_omp_sections (gimple_seq, tree); gimple *gimple_build_omp_sections_switch (void); gomp_single *gimple_build_omp_single (gimple_seq, tree); -gomp_target *gimple_build_omp_target (gimple_seq, int, tree); +gomp_target *gimple_build_omp_target (gimple_seq, int, tree, gimple_seq = NULL); gomp_teams *gimple_build_omp_teams (gimple_seq, tree); gomp_atomic_load *gimple_build_omp_atomic_load (tree, tree, enum omp_memory_order); @@ -6380,6 +6383,38 @@ gimple_omp_target_set_data_arg (gomp_target *omp_target_stmt, } +/* Return the Gimple sequence used to store loops for OpenMP iterators used + by OMP_TARGET_STMT. */ + +inline gimple_seq +gimple_omp_target_iterator_loops (const gomp_target *omp_target_stmt) +{ + return omp_target_stmt->iterator_loops; +} + + +/* Return a pointer to the Gimple sequence used to store loops for OpenMP + iterators used by OMP_TARGET GS. */ + +inline gimple_seq * +gimple_omp_target_iterator_loops_ptr (gimple *gs) +{ + gomp_target *omp_target_stmt = as_a <gomp_target *> (gs); + return &omp_target_stmt->iterator_loops; +} + + +/* Set ITERATOR_LOOPS to be the Gimple sequence used to store loops + constructed for OpenMP iterators in OMP_TARGET_STMT. */ + +inline void +gimple_omp_target_set_iterator_loops (gomp_target *omp_target_stmt, + gimple_seq iterator_loops) +{ + omp_target_stmt->iterator_loops = iterator_loops; +} + + /* Return the clauses associated with OMP_TEAMS GS. */ inline tree diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index fbf47dd..ca1fa21 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -9891,6 +9891,373 @@ build_omp_iterator_loop (tree it, gimple_seq *pre_p, tree *last_bind) return p; } + +/* Callback for walk_tree to find a VAR_DECL (stored in DATA) in the + tree TP. */ + +static tree +find_var_decl (tree *tp, int *, void *data) +{ + if (*tp == (tree) data) + return *tp; + + return NULL_TREE; +} + +/* Returns an element-by-element copy of OMP iterator tree IT. */ + +static tree +copy_omp_iterator (tree it, int elem_count = -1) +{ + if (elem_count < 0) + elem_count = TREE_VEC_LENGTH (it); + tree new_it = make_tree_vec (elem_count); + for (int i = 0; i < TREE_VEC_LENGTH (it); i++) + TREE_VEC_ELT (new_it, i) = TREE_VEC_ELT (it, i); + + return new_it; +} + +/* Helper function for walk_tree in remap_omp_iterator_var. */ + +static tree +remap_omp_iterator_var_1 (tree *tp, int *, void *data) +{ + tree old_var = ((tree *) data)[0]; + tree new_var = ((tree *) data)[1]; + + if (*tp == old_var) + *tp = new_var; + return NULL_TREE; +} + +/* Replace instances of OLD_VAR in TP with NEW_VAR. */ + +static void +remap_omp_iterator_var (tree *tp, tree old_var, tree new_var) +{ + tree vars[2] = { old_var, new_var }; + walk_tree (tp, remap_omp_iterator_var_1, vars, NULL); +} + +/* Scan through all clauses using OpenMP iterators in LIST_P. If any + clauses have iterators with variables that are not used by the clause + decl or size, issue a warning and replace the iterator with a copy with + the unused variables removed. */ + +static void +remove_unused_omp_iterator_vars (tree *list_p) +{ + auto_vec< vec<tree> > iter_vars; + auto_vec<tree> new_iterators; + + for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) + { + if (!OMP_CLAUSE_HAS_ITERATORS (c)) + continue; + auto_vec<tree> vars; + bool need_new_iterators = false; + for (tree it = OMP_CLAUSE_ITERATORS (c); it; it = TREE_CHAIN (it)) + { + tree var = TREE_VEC_ELT (it, 0); + tree t = walk_tree (&OMP_CLAUSE_DECL (c), find_var_decl, var, NULL); + if (t == NULL_TREE) + t = walk_tree (&OMP_CLAUSE_SIZE (c), find_var_decl, var, NULL); + if (t == NULL_TREE) + { + need_new_iterators = true; + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO + || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FROM)) + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM) + warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp, + "iterator variable %qE not used in clause " + "expression", DECL_NAME (var)); + } + else + vars.safe_push (var); + } + if (!need_new_iterators) + continue; + if (need_new_iterators && vars.is_empty ()) + { + /* No iteration variables are used in the clause - remove the + iterator from the clause. */ + OMP_CLAUSE_ITERATORS (c) = NULL_TREE; + continue; + } + + /* If a new iterator has been created for the current set of used + iterator variables, then use that as the iterator. Otherwise, + create a new iterator for the current iterator variable set. */ + unsigned i; + for (i = 0; i < iter_vars.length (); i++) + { + if (vars.length () != iter_vars[i].length ()) + continue; + bool identical_p = true; + for (unsigned j = 0; j < vars.length () && identical_p; j++) + identical_p = vars[j] == iter_vars[i][j]; + + if (identical_p) + break; + } + if (i < iter_vars.length ()) + OMP_CLAUSE_ITERATORS (c) = new_iterators[i]; + else + { + tree new_iters = NULL_TREE; + tree *new_iters_p = &new_iters; + tree new_vars = NULL_TREE; + tree *new_vars_p = &new_vars; + i = 0; + for (tree it = OMP_CLAUSE_ITERATORS (c); it && i < vars.length(); + it = TREE_CHAIN (it)) + { + tree var = TREE_VEC_ELT (it, 0); + if (var == vars[i]) + { + *new_iters_p = copy_omp_iterator (it); + *new_vars_p = build_decl (OMP_CLAUSE_LOCATION (c), VAR_DECL, + DECL_NAME (var), TREE_TYPE (var)); + DECL_ARTIFICIAL (*new_vars_p) = 1; + DECL_CONTEXT (*new_vars_p) = DECL_CONTEXT (var); + TREE_VEC_ELT (*new_iters_p, 0) = *new_vars_p; + new_iters_p = &TREE_CHAIN (*new_iters_p); + new_vars_p = &DECL_CHAIN (*new_vars_p); + i++; + } + } + tree new_block = make_node (BLOCK); + BLOCK_VARS (new_block) = new_vars; + TREE_VEC_ELT (new_iters, 5) = new_block; + new_iterators.safe_push (new_iters); + iter_vars.safe_push (vars.copy ()); + OMP_CLAUSE_ITERATORS (c) = new_iters; + } + + /* Remap clause to use the new variables. */ + i = 0; + for (tree it = OMP_CLAUSE_ITERATORS (c); it; it = TREE_CHAIN (it)) + { + tree old_var = vars[i++]; + tree new_var = TREE_VEC_ELT (it, 0); + remap_omp_iterator_var (&OMP_CLAUSE_DECL (c), old_var, new_var); + remap_omp_iterator_var (&OMP_CLAUSE_SIZE (c), old_var, new_var); + } + } + + for (unsigned i = 0; i < iter_vars.length (); i++) + iter_vars[i].release (); +} + +struct iterator_loop_info_t +{ + tree bind; + tree count; + tree index; + tree body_label; + auto_vec<tree> clauses; +}; + +typedef hash_map<tree, iterator_loop_info_t> iterator_loop_info_map_t; + +/* Builds a loop to expand any OpenMP iterators in the clauses in LIST_P, + reusing any previously built loops if they use the same set of iterators. + Generated Gimple statements are placed into LOOPS_SEQ_P. The clause + iterators are updated with information on how and where to insert code into + the loop body. */ + +static void +build_omp_iterators_loops (tree *list_p, gimple_seq *loops_seq_p) +{ + iterator_loop_info_map_t loops; + + for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c)) + { + if (!OMP_CLAUSE_HAS_ITERATORS (c)) + continue; + + bool built_p; + iterator_loop_info_t &loop + = loops.get_or_insert (OMP_CLAUSE_ITERATORS (c), &built_p); + + if (!built_p) + { + loop.count = compute_omp_iterator_count (OMP_CLAUSE_ITERATORS (c), + loops_seq_p); + if (!loop.count) + continue; + if (integer_zerop (loop.count)) + warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp, + "iteration count is zero"); + + loop.bind = NULL_TREE; + tree *body = build_omp_iterator_loop (OMP_CLAUSE_ITERATORS (c), + loops_seq_p, &loop.bind); + + loop.index = create_tmp_var (sizetype); + SET_EXPR_LOCATION (loop.bind, OMP_CLAUSE_LOCATION (c)); + + /* BEFORE LOOP: */ + /* idx = -1; */ + /* This should be initialized to before the individual elements, + as idx is pre-incremented in the loop body. */ + gimple *assign = gimple_build_assign (loop.index, size_int (-1)); + gimple_seq_add_stmt (loops_seq_p, assign); + + /* IN LOOP BODY: */ + /* Create a label so we can find this point later. */ + loop.body_label = create_artificial_label (OMP_CLAUSE_LOCATION (c)); + tree tem = build1 (LABEL_EXPR, void_type_node, loop.body_label); + append_to_statement_list_force (tem, body); + + /* idx += 2; */ + tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, + void_type_node, loop.index, + size_binop (PLUS_EXPR, loop.index, size_int (2))); + append_to_statement_list_force (tem, body); + } + + /* Create array to hold expanded values. */ + tree last_count_2 = size_binop (MULT_EXPR, loop.count, size_int (2)); + tree arr_length = size_binop (PLUS_EXPR, last_count_2, size_int (1)); + tree elems = NULL_TREE; + if (TREE_CONSTANT (arr_length)) + { + tree type = build_array_type (ptr_type_node, + build_index_type (arr_length)); + elems = create_tmp_var_raw (type, "omp_iter_data"); + TREE_ADDRESSABLE (elems) = 1; + gimple_add_tmp_var (elems); + } + else + { + /* Handle dynamic sizes. */ + sorry ("dynamic iterator sizes not implemented yet"); + } + + /* BEFORE LOOP: */ + /* elems[0] = count; */ + tree lhs = build4 (ARRAY_REF, ptr_type_node, elems, size_int (0), + NULL_TREE, NULL_TREE); + tree tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, + void_type_node, lhs, loop.count); + gimplify_and_add (tem, loops_seq_p); + + /* Make a copy of the iterator with extra info at the end. */ + int elem_count = TREE_VEC_LENGTH (OMP_CLAUSE_ITERATORS (c)); + tree new_iterator = copy_omp_iterator (OMP_CLAUSE_ITERATORS (c), + elem_count + 3); + TREE_VEC_ELT (new_iterator, elem_count) = loop.body_label; + TREE_VEC_ELT (new_iterator, elem_count + 1) = elems; + TREE_VEC_ELT (new_iterator, elem_count + 2) = loop.index; + TREE_CHAIN (new_iterator) = TREE_CHAIN (OMP_CLAUSE_ITERATORS (c)); + OMP_CLAUSE_ITERATORS (c) = new_iterator; + + loop.clauses.safe_push (c); + } + + /* Now gimplify and add all the loops that were built. */ + for (hash_map<tree, iterator_loop_info_t>::iterator it = loops.begin (); + it != loops.end (); ++it) + gimplify_and_add ((*it).second.bind, loops_seq_p); +} + +/* Helper function for enter_omp_iterator_loop_context. */ + +static gimple_seq * +enter_omp_iterator_loop_context_1 (tree iterator, gimple_seq *loops_seq_p) +{ + /* Drill into the nested bind expressions to get to the loop body. */ + for (gimple_stmt_iterator gsi = gsi_start (*loops_seq_p); + !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + + switch (gimple_code (stmt)) + { + case GIMPLE_BIND: + { + gbind *bind_stmt = as_a<gbind *> (stmt); + gimple_push_bind_expr (bind_stmt); + gimple_seq *bind_body_p = gimple_bind_body_ptr (bind_stmt); + gimple_seq *seq = + enter_omp_iterator_loop_context_1 (iterator, bind_body_p); + if (seq) + return seq; + gimple_pop_bind_expr (); + } + break; + case GIMPLE_TRY: + { + gimple_seq *try_eval_p = gimple_try_eval_ptr (stmt); + gimple_seq *seq = + enter_omp_iterator_loop_context_1 (iterator, try_eval_p); + if (seq) + return seq; + } + break; + case GIMPLE_LABEL: + { + glabel *label_stmt = as_a<glabel *> (stmt); + tree label = gimple_label_label (label_stmt); + if (label == TREE_VEC_ELT (iterator, 6)) + return loops_seq_p; + } + break; + default: + break; + } + } + + return NULL; +} + +/* Enter the Gimplification context in LOOPS_SEQ_P for the iterator loop + associated with OpenMP clause C. Returns the gimple_seq for the loop body + if C has OpenMP iterators, or ALT_SEQ_P if not. */ + +static gimple_seq * +enter_omp_iterator_loop_context (tree c, gimple_seq *loops_seq_p, + gimple_seq *alt_seq_p) +{ + if (!OMP_CLAUSE_HAS_ITERATORS (c)) + return alt_seq_p; + + push_gimplify_context (); + + gimple_seq *seq = enter_omp_iterator_loop_context_1 (OMP_CLAUSE_ITERATORS (c), + loops_seq_p); + gcc_assert (seq); + return seq; +} + +/* Enter the Gimplification context in STMT for the iterator loop associated + with OpenMP clause C. Returns the gimple_seq for the loop body if C has + OpenMP iterators, or ALT_SEQ_P if not. */ + +gimple_seq * +enter_omp_iterator_loop_context (tree c, gomp_target *stmt, + gimple_seq *alt_seq_p) +{ + gimple_seq *loops_seq_p = gimple_omp_target_iterator_loops_ptr (stmt); + return enter_omp_iterator_loop_context (c, loops_seq_p, alt_seq_p); +} + +/* Exit the Gimplification context for the OpenMP clause C. */ + +void +exit_omp_iterator_loop_context (tree c) +{ + if (!OMP_CLAUSE_HAS_ITERATORS (c)) + return; + while (!gimplify_ctxp->bind_expr_stack.is_empty ()) + gimple_pop_bind_expr (); + pop_gimplify_context (NULL); +} + /* If *LIST_P contains any OpenMP depend clauses with iterators, lower all the depend clauses by populating corresponding depend array. Returns 0 if there are no such depend clauses, or @@ -13217,7 +13584,8 @@ omp_instantiate_implicit_mappers (splay_tree_node n, void *data) static void gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, enum omp_region_type region_type, - enum tree_code code) + enum tree_code code, + gimple_seq *loops_seq_p = NULL) { using namespace omp_addr_tokenizer; struct gimplify_omp_ctx *ctx, *outer_ctx; @@ -13988,23 +14356,24 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, if (OMP_CLAUSE_SIZE (c) == NULL_TREE) OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl) : TYPE_SIZE_UNIT (TREE_TYPE (decl)); - if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, - NULL, is_gimple_val, fb_rvalue) == GS_ERROR) + gimple_seq *seq_p; + seq_p = enter_omp_iterator_loop_context (c, loops_seq_p, pre_p); + if (gimplify_expr (&OMP_CLAUSE_SIZE (c), seq_p, NULL, + is_gimple_val, fb_rvalue) == GS_ERROR) { remove = true; + exit_omp_iterator_loop_context (c); break; } if (!DECL_P (decl)) { - if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, - NULL, is_gimple_lvalue, fb_lvalue) - == GS_ERROR) - { - remove = true; - break; - } + if (gimplify_expr (&OMP_CLAUSE_DECL (c), seq_p, NULL, + is_gimple_lvalue, fb_lvalue) == GS_ERROR) + remove = true; + exit_omp_iterator_loop_context (c); break; } + exit_omp_iterator_loop_context (c); goto do_notice; case OMP_CLAUSE__MAPPER_BINDING_: @@ -15035,7 +15404,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data) static void gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, - enum tree_code code) + enum tree_code code, + gimple_seq *loops_seq_p = NULL) { struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; tree *orig_list_p = list_p; @@ -15406,12 +15776,14 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, : TYPE_SIZE_UNIT (TREE_TYPE (decl)); } gimplify_omp_ctxp = ctx->outer_context; - if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, NULL, + gimple_seq *seq_p; + seq_p = enter_omp_iterator_loop_context (c, loops_seq_p, pre_p); + if (gimplify_expr (&OMP_CLAUSE_SIZE (c), seq_p, NULL, is_gimple_val, fb_rvalue) == GS_ERROR) { gimplify_omp_ctxp = ctx; remove = true; - break; + goto end_adjust_omp_map_clause; } else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER || (OMP_CLAUSE_MAP_KIND (c) @@ -15420,7 +15792,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST) { OMP_CLAUSE_SIZE (c) - = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL, + = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), seq_p, NULL, false); if ((ctx->region_type & ORT_TARGET) != 0) omp_add_variable (ctx, OMP_CLAUSE_SIZE (c), @@ -15461,7 +15833,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)) { remove = true; - break; + goto end_adjust_omp_map_clause; } /* If we have a DECL_VALUE_EXPR (e.g. this is a class member and/or a variable captured in a lambda closure), look through that now @@ -15477,7 +15849,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, decl = OMP_CLAUSE_DECL (c) = DECL_VALUE_EXPR (decl); if (TREE_CODE (decl) == TARGET_EXPR) { - if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL, + if (gimplify_expr (&OMP_CLAUSE_DECL (c), seq_p, NULL, is_gimple_lvalue, fb_lvalue) == GS_ERROR) remove = true; } @@ -15564,19 +15936,19 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, /* If we have e.g. map(struct: *var), don't gimplify the argument since omp-low.cc wants to see the decl itself. */ if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT) - break; + goto end_adjust_omp_map_clause; /* We've already partly gimplified this in gimplify_scan_omp_clauses. Don't do any more. */ if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c)) - break; + goto end_adjust_omp_map_clause; gimplify_omp_ctxp = ctx->outer_context; - if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue, + if (gimplify_expr (pd, seq_p, NULL, is_gimple_lvalue, fb_lvalue) == GS_ERROR) remove = true; gimplify_omp_ctxp = ctx; - break; + goto end_adjust_omp_map_clause; } if ((code == OMP_TARGET @@ -15709,6 +16081,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))) move_attach = true; +end_adjust_omp_map_clause: + exit_omp_iterator_loop_context (c); break; case OMP_CLAUSE_TO: @@ -18347,11 +18721,18 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p) gcc_unreachable (); } + gimple_seq iterator_loops_seq = NULL; + if (TREE_CODE (expr) == OMP_TARGET) + { + remove_unused_omp_iterator_vars (&OMP_CLAUSES (expr)); + build_omp_iterators_loops (&OMP_CLAUSES (expr), &iterator_loops_seq); + } + bool save_in_omp_construct = in_omp_construct; if ((ort & ORT_ACC) == 0) in_omp_construct = false; gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort, - TREE_CODE (expr)); + TREE_CODE (expr), &iterator_loops_seq); if (TREE_CODE (expr) == OMP_TARGET) optimize_target_teams (expr, pre_p); if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0 @@ -18390,7 +18771,7 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p) else gimplify_and_add (OMP_BODY (expr), &body); gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr), - TREE_CODE (expr)); + TREE_CODE (expr), &iterator_loops_seq); in_omp_construct = save_in_omp_construct; switch (TREE_CODE (expr)) @@ -18433,7 +18814,7 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p) break; case OMP_TARGET: stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION, - OMP_CLAUSES (expr)); + OMP_CLAUSES (expr), iterator_loops_seq); break; case OMP_TARGET_DATA: /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed @@ -18508,10 +18889,16 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p) default: gcc_unreachable (); } + + gimple_seq iterator_loops_seq = NULL; + remove_unused_omp_iterator_vars (&OMP_STANDALONE_CLAUSES (expr)); + build_omp_iterators_loops (&OMP_STANDALONE_CLAUSES (expr), + &iterator_loops_seq); + gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p, - ort, TREE_CODE (expr)); + ort, TREE_CODE (expr), &iterator_loops_seq); gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr), - TREE_CODE (expr)); + TREE_CODE (expr), &iterator_loops_seq); if (TREE_CODE (expr) == OACC_UPDATE && omp_find_clause (OMP_STANDALONE_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT)) @@ -18575,7 +18962,8 @@ gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p) gcc_unreachable (); } } - stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr)); + stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr), + iterator_loops_seq); gimplify_seq_add_stmt (pre_p, stmt); *expr_p = NULL_TREE; diff --git a/gcc/gimplify.h b/gcc/gimplify.h index b66ceb3..80c335e 100644 --- a/gcc/gimplify.h +++ b/gcc/gimplify.h @@ -79,6 +79,10 @@ extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *, extern tree omp_get_construct_context (void); int omp_has_novariants (void); +extern gimple_seq *enter_omp_iterator_loop_context (tree, gomp_target *, + gimple_seq * = NULL); +extern void exit_omp_iterator_loop_context (tree); + extern void gimplify_type_sizes (tree, gimple_seq *); extern void gimplify_one_sizepos (tree *, gimple_seq *); extern gbind *gimplify_body (tree, bool); diff --git a/gcc/gsstruct.def b/gcc/gsstruct.def index bfe0901..34adc86 100644 --- a/gcc/gsstruct.def +++ b/gcc/gsstruct.def @@ -44,6 +44,7 @@ DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false) DEFGSSTRUCT(GSS_OMP_CRITICAL, gomp_critical, false) DEFGSSTRUCT(GSS_OMP_FOR, gomp_for, false) DEFGSSTRUCT(GSS_OMP_PARALLEL_LAYOUT, gimple_statement_omp_parallel_layout, false) +DEFGSSTRUCT(GSS_OMP_TARGET, gomp_target, false) DEFGSSTRUCT(GSS_OMP_TASK, gomp_task, false) DEFGSSTRUCT(GSS_OMP_SECTIONS, gomp_sections, false) DEFGSSTRUCT(GSS_OMP_SINGLE_LAYOUT, gimple_statement_omp_single_layout, false) diff --git a/gcc/match.pd b/gcc/match.pd index 82e6e29..06a4a91 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5508,16 +5508,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (convert @0))) /* Strip inner integral conversions that do not change precision or size, or - zero-extend while keeping the same size (for bool-to-char). */ + zero-extend while keeping the same size (for bool-to-char). + However, keep this conversion if the result is an extended _BitInt, + since it may rely on this conversion to extend properly. */ + (simplify (view_convert (convert@0 @1)) + (with { + bool extended_bitint = false; + if (BITINT_TYPE_P (TREE_TYPE (@0))) + { + struct bitint_info info; + extended_bitint + = targetm.c.bitint_type_info (TYPE_PRECISION (TREE_TYPE (@0)), + &info); + extended_bitint = extended_bitint && info.extended; + } + } (if ((INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) && (INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) + && !extended_bitint && TYPE_SIZE (TREE_TYPE (@0)) == TYPE_SIZE (TREE_TYPE (@1)) && (TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1)) || (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (TREE_TYPE (@1)) && TYPE_UNSIGNED (TREE_TYPE (@1))))) - (view_convert @1))) + (view_convert @1)))) /* Simplify a view-converted empty or single-element constructor. */ (simplify diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc index e1036ad..9d80a35 100644 --- a/gcc/omp-low.cc +++ b/gcc/omp-low.cc @@ -12651,6 +12651,63 @@ lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx) } } + /* Set EXPR as the hostaddr expression that should result from the clause C + in the target statement STMT. Returns the tree that should be + passed as the hostaddr (a pointer to the array containing the expanded + hostaddrs and sizes of the clause). */ + +static tree +lower_omp_map_iterator_expr (tree expr, tree c, gomp_target *stmt) +{ + if (!OMP_CLAUSE_HAS_ITERATORS (c)) + return expr; + + tree iterator = OMP_CLAUSE_ITERATORS (c); + tree elems = TREE_VEC_ELT (iterator, 7); + tree index = TREE_VEC_ELT (iterator, 8); + gimple_seq *loop_body_p = enter_omp_iterator_loop_context (c, stmt); + + /* IN LOOP BODY: */ + /* elems[idx] = <expr>; */ + tree lhs = build4 (ARRAY_REF, ptr_type_node, elems, index, + NULL_TREE, NULL_TREE); + tree mod_expr = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, + void_type_node, lhs, expr); + gimplify_and_add (mod_expr, loop_body_p); + exit_omp_iterator_loop_context (c); + + return build_fold_addr_expr_with_type (elems, ptr_type_node); +} + +/* Set SIZE as the size expression that should result from the clause C + in the target statement STMT. Returns the tree that should be + passed as the clause size (a size_int with the value SIZE_MAX, indicating + that the clause uses an iterator). */ + +static tree +lower_omp_map_iterator_size (tree size, tree c, gomp_target *stmt) +{ + if (!OMP_CLAUSE_HAS_ITERATORS (c)) + return size; + + tree iterator = OMP_CLAUSE_ITERATORS (c); + tree elems = TREE_VEC_ELT (iterator, 7); + tree index = TREE_VEC_ELT (iterator, 8); + gimple_seq *loop_body_p = enter_omp_iterator_loop_context (c, stmt); + + /* IN LOOP BODY: */ + /* elems[idx+1] = <size>; */ + tree lhs = build4 (ARRAY_REF, ptr_type_node, elems, + size_binop (PLUS_EXPR, index, size_int (1)), + NULL_TREE, NULL_TREE); + tree mod_expr = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR, + void_type_node, lhs, size); + gimplify_and_add (mod_expr, loop_body_p); + exit_omp_iterator_loop_context (c); + + return size_int (SIZE_MAX); +} + /* Lower the GIMPLE_OMP_TARGET in the current statement in GSI_P. CTX holds context information for the directive. */ @@ -12820,6 +12877,11 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) deep_map_cnt = extra; } + if (deep_map_cnt + && OMP_CLAUSE_HAS_ITERATORS (c)) + sorry ("iterators used together with deep mapping are not " + "supported yet"); + if (!DECL_P (var)) { if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP @@ -13234,6 +13296,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) *p = build_fold_indirect_ref (nd); } v = build_fold_addr_expr_with_type (v, ptr_type_node); + v = lower_omp_map_iterator_expr (v, c, stmt); gimplify_assign (x, v, &ilist); nc = NULL_TREE; } @@ -13307,12 +13370,17 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) && TREE_CODE (TREE_TYPE (ovar)) == ARRAY_TYPE) { gcc_assert (offloaded); - tree avar - = create_tmp_var (TREE_TYPE (TREE_TYPE (x))); - mark_addressable (avar); - gimplify_assign (avar, build_fold_addr_expr (var), &ilist); - talign = DECL_ALIGN_UNIT (avar); + tree avar = build_fold_addr_expr (var); + if (!OMP_CLAUSE_ITERATORS (c)) + { + tree tmp = create_tmp_var (TREE_TYPE (TREE_TYPE (x))); + mark_addressable (tmp); + gimplify_assign (tmp, avar, &ilist); + avar = tmp; + } + talign = TYPE_ALIGN_UNIT (TREE_TYPE (TREE_TYPE (x))); avar = build_fold_addr_expr (avar); + avar = lower_omp_map_iterator_expr (avar, c, stmt); gimplify_assign (x, avar, &ilist); } else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE) @@ -13392,6 +13460,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) if (s == NULL_TREE) s = TYPE_SIZE_UNIT (TREE_TYPE (ovar)); s = fold_convert (size_type_node, s); + s = lower_omp_map_iterator_size (s, c, stmt); purpose = size_int (map_idx++); CONSTRUCTOR_APPEND_ELT (vsize, purpose, s); if (TREE_CODE (s) != INTEGER_CST) @@ -14324,6 +14393,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) gimple_omp_set_body (stmt, new_body); } + gsi_insert_seq_before (gsi_p, gimple_omp_target_iterator_loops (stmt), + GSI_SAME_STMT); + gimple_omp_target_set_iterator_loops (stmt, NULL); bind = gimple_build_bind (NULL, NULL, tgt_bind ? gimple_bind_block (tgt_bind) : NULL_TREE); diff --git a/gcc/rust/ChangeLog b/gcc/rust/ChangeLog index f103c7e..f960ef2 100644 --- a/gcc/rust/ChangeLog +++ b/gcc/rust/ChangeLog @@ -1,3 +1,2391 @@ +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * Make-lang.in (rust-readonly-check2.cc): + Add read-only check on HIR + * checks/errors/rust-readonly-check2.cc (ReadonlyChecker): + Add read-only check on HIR + * checks/errors/rust-readonly-check2.h (ReadonlyChecker): + Add read-only check on HIR + +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): + Call base class's accept_vis method + +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): + Add check before calling `get_trait_ref()` + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * expand/rust-macro-builtins-helpers.cc + (try_extract_string_literal_from_fragment): Perform static_cast + to AST::LiteralExpr only after it's verified that an AST::Expr + is a literal. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * util/rust-attribute-values.h + (Attributes::RUSTC_ARGS_REQUIRED_CONST): New constexpr variable. + * util/rust-attributes.cc (__definitions): New entry for + RUSTC_ARGS_REQUIRED_CONST. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-ast.cc (AttributeParser::parse_meta_item_inner): + Handle removal of AttributeParser-specific functions. + (AttributeParser::parse_path_meta_item): Likewise. + (AttributeParser::parse_meta_item_seq): Likewise. + (AttributeParser::parse_meta_item_lit): Likewise. + (AttributeParser::parse_literal): Remove function. + (AttributeParser::parse_simple_path): Likewise. + (AttributeParser::parse_simple_path_segment): Likewise. + (AttributeParser::peek_token): Likewise. + (AttributeParser::skip_token): Likewise. + * ast/rust-macro.h (AttributeParser::parse_simple_path): + Likewise. + (AttributeParser::parse_simple_path_segment): Likewise. + (AttributeParser::parse_literal): Likewise. + (AttributeParser::peek_token): Likewise. + (AttributeParser::skip_token): Likewise. + * parse/rust-parse.h (Parser): Make AttributeParser a friend + class. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * backend/rust-compile-expr.cc (CompileExpr::visit): Add proper handling + of the node. + * rust-backend.h (lookup_field): Declare it. + * rust-gcc.cc (lookup_field): Add forked implementation from gcc/c/. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-ast.cc (AttributeParser::parse_path_meta_item): Catch + parse_expr returning nullptr and remove defunct comment. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * Make-lang.in (GRS_OBJS): Add entries. + * parse/rust-parse-impl.h: Adjust header comment. + (Parser::parse_lifetime_params_objs): Fix bug and add comment. + (Parser::unexpected_token): Likewise. + * parse/rust-parse.h: Remove inclusion of "rust-parse-impl.h". + * parse/rust-parse-impl-lexer.cc: New file. + * parse/rust-parse-impl-macro.cc: New file. + * parse/rust-parse-impl-proc-macro.cc: New file. + +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit): + Fix object copying issue causing pointer inconsistency + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * ast/rust-ast.cc (AttributeParser::parse_path_meta_item): Parse + expression instead of literal. Update variant name. + (MetaItemPathLit::to_attribute): Remove function. + (AttributeParser::parse_path_meta_item): Update name. + (MetaItemPathLit::check_cfg_predicate): Likewise. + (MetaItemPathExpr::check_cfg_predicate): Likewise. + (MetaItemPathLit::accept_vis): Likewise. + (MetaItemPathExpr::accept_vis): Likewise. + * ast/rust-ast-collector.h: Update prototype and adapt code to new + expression. + * ast/rust-ast-collector.cc: Update code to expr. + * ast/rust-ast-full-decls.h (class MetaItemPathLit): Likewise. + (class MetaItemPathExpr): Likewise. + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. + * ast/rust-ast-visitor.h: Likewise. + * ast/rust-ast.h (class MetaItemPathLit): Rename class from here... + (class MetaItemPathExpr): ... to here. + * ast/rust-expr.h (class MetaItemPathLit): Rename class from here... + (class MetaItemPathExpr): ...to here. + * expand/rust-derive.h: Update class name. + * expand/rust-expand-visitor.cc (ExpandVisitor::visit): Likewise. + * expand/rust-expand-visitor.h: Likewise. + * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise. + * hir/rust-ast-lower-base.h: Likewise. + * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise. + * resolve/rust-ast-resolve-base.h: Likewise. + * resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit): + Likewise. + * resolve/rust-early-name-resolver.h: Likewise. + * util/rust-attributes.cc (AttributeChecker::visit): Likewise. + * util/rust-attributes.h: Likewise. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-tyty-subst.cc (SubstitutionRef::infer_substitions): remove debug + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-type-util.cc (unify_site_and): improve debug + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-autoderef.cc: remove useless assertion + * typecheck/rust-coercion.cc (TypeCoercionRules::coerce_unsafe_ptr): refactor + (TypeCoercionRules::coerce_borrowed_pointer): remove FIXME this is fine + * typecheck/rust-hir-inherent-impl-overlap.h: use types_compatable + * typecheck/rust-hir-path-probe.cc (PathProbeType::PathProbeType): remove const + (PathProbeType::Probe): likewise + (PathProbeImplTrait::PathProbeImplTrait): likewise + (PathProbeImplTrait::Probe): likewise + * typecheck/rust-hir-path-probe.h: likewise + * typecheck/rust-hir-type-check-base.cc (walk_types_to_constrain): likewise + * typecheck/rust-hir-type-check-base.h: likewise + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): use types_compatable + * typecheck/rust-hir-type-check.h: remove const + * typecheck/rust-typecheck-context.cc (TypeCheckContext::insert_associated_impl_mapping): + likewise + (TypeCheckContext::lookup_associated_impl_mapping_for_self): remove can_Eq + * typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::is_equal): likewise + * typecheck/rust-tyty-subst.cc (SubstitutionArg::get_tyty): remove const version + * typecheck/rust-tyty-subst.h: likewise + * typecheck/rust-tyty.cc (BaseType::get_root): likewise + * typecheck/rust-tyty.h: likewise + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-tyty-subst.cc: track the const generic + * typecheck/rust-tyty.cc (ConstType::is_equal): finish the is_equal + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * hir/rust-hir-dump.cc (Dump::Dump): Initialize flag. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * hir/rust-ast-lower-pattern.cc (ASTLoweringPattern::ASTLoweringPattern): + flag was not initialized in the constructor. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit): Remove + use after move. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * expand/rust-macro-builtins-helpers.cc: Remove use after move. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * ast/rust-ast-collector.cc: Add support for the 2 new classes. + * ast/rust-ast-collector.h: Header file update for above. + * ast/rust-ast-full-decls.h: Add forward decls for the 2 new classes. + * ast/rust-ast-visitor.cc: Add visit support for the 2 new classes. + * ast/rust-ast-visitor.h: Header file update for above. + * ast/rust-pattern.cc: Implementation of certain methods for the 2 new classes. + * ast/rust-pattern.h: Define the 2 new classes. Update SlicePattern to be able to hold + 2 kinds of items - SlicePatternItemsNoRest or SlicePatternItemsRest. + * expand/rust-cfg-strip.cc: Add support for the 2 new classes. + * expand/rust-cfg-strip.h: Header file update for above. + * expand/rust-derive.h: Add visits for the 2 new classes. + * hir/rust-ast-lower-base.cc: Add visits for the 2 new classes. + * hir/rust-ast-lower-base.h: Header file update for above. + * hir/rust-ast-lower-pattern.cc: Update lowering of SlicePattern to support + SlicePatternItemsNoRest. + * parse/rust-parse-impl.h (parse_slice_pattern()): Add support for parsing DOT_DOT into + respective SlicePatternItems. + * resolve/rust-ast-resolve-base.cc: Add visits for the 2 new classes. + * resolve/rust-ast-resolve-base.h: Header file update for above. + * resolve/rust-ast-resolve-pattern.cc: Update SlicePattern resolution to support new + classes. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-tyty-subst.cc: fix check for total arguments + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): create infer variable + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * hir/rust-hir-dump.cc (Dump::visit): check for expression + * hir/tree/rust-hir.cc (AnonConst::as_string): likewise + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * ast/rust-ast-collector.cc (TokenCollector::visit): check for value + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): formatting + * typecheck/rust-tyty-variance-analysis-private.h: likewise + * typecheck/rust-tyty.cc (VariantDef::clone): likewise + (VariantDef::monomorphized_clone): likewise + * typecheck/rust-tyty.h: likewise + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-base.cc: useful debug + * backend/rust-compile-stmt.cc (CompileStmt::visit): likewise + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): fold the capacity into ConstType + * hir/tree/rust-hir-generic-param.h: make const + * hir/tree/rust-hir-path.h: take into account const arguments now + * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::resolve_literal): needs const + * typecheck/rust-hir-type-check-base.h: add error handling for const supported locations + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): const type the arrays + * typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit): update + (TypeCheckImplItem::visit): likewise + * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): likewise + (TypeCheckItem::resolve_impl_block_substitutions): likewise + * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): wrap up const type + * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise + (TypeResolveGenericParam::visit): likewise + (TypeResolveGenericParam::apply_trait_bounds): remove HIR::Generic from Param + * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn): cleanup + * typecheck/rust-tyty-subst.cc (SubstitutionParamMapping::SubstitutionParamMapping): + handle const generics + (SubstitutionParamMapping::get_type_representation): likewise + (SubstitutionParamMapping::param_has_default_ty): likewise + (SubstitutionParamMapping::get_default_ty): likewise + (SubstitutionRef::infer_substitions): likewise + * typecheck/rust-tyty-subst.h: likewise + * typecheck/rust-tyty-util.cc (TyVar::get_implicit_const_infer_var): new helper + * typecheck/rust-tyty-util.h (class ConstType): likewise + * typecheck/rust-tyty.cc (BaseType::is_concrete): check for array const concrete + (ArrayType::as_string): update to const + (ArrayType::handle_substitions): likewise + (ParamType::ParamType): likewise + (ParamType::get_generic_param): likewise + (ParamType::clone): likewise + (ConstType::ConstType): likewise + (ConstType::set_value): likewise + (ConstType::clone): likewise + (ConstType::get_generic_param): likewise + (generate_tree_str): new helper to pretty print gimple + (ConstType::get_name): uses the generate_tree_str + (ConstType::handle_substitions): handle const infer's + * typecheck/rust-tyty.h (RUST_TYTY): likewise + * typecheck/rust-unify.cc (UnifyRules::expect_array): likewise + (UnifyRules::expect_const): likewise + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): error_mark_node for const types + * backend/rust-compile-type.h: boilerplate + * checks/errors/borrowck/rust-bir-fact-collector.h: likewise + * checks/errors/borrowck/rust-bir-place.h: likewise + * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::check_base_type_privacy): + likewise + * typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): likewise + * typecheck/rust-substitution-mapper.h: likewise + * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::assemble_marker_builtins): likewise + * typecheck/rust-tyty-call.h: likewise + * typecheck/rust-tyty-cmp.h (class ConstCmp): likewise + * typecheck/rust-tyty-variance-analysis-private.h: likewise + * typecheck/rust-tyty-visitor.h: likewise + * typecheck/rust-tyty.cc (TypeKindFormat::to_string): likewise + (BaseType::is_unit): likewise + (BaseType::has_substitutions_defined): likewise + (BaseType::needs_generic_substitutions): likewise + (ConstType::ConstType): likewise + (ConstType::accept_vis): likewise + (ConstType::as_string): likewise + (ConstType::can_eq): likewise + (ConstType::clone): likewise + (ConstType::get_symbol): likewise + (ConstType::get_generic_param): likewise + (ConstType::can_resolve): likewise + (ConstType::resolve): likewise + (ConstType::get_name): likewise + (ConstType::is_equal): likewise + (ConstType::handle_substitions): likewise + * typecheck/rust-tyty.h (enum TypeKind): new tyty_kind + (class ConstType): new type + * typecheck/rust-unify.cc (UnifyRules::go): Handle a const type unify + (UnifyRules::expect_inference_variable): likewise + (UnifyRules::expect_adt): likewise + (UnifyRules::expect_str): likewise + (UnifyRules::expect_reference): likewise + (UnifyRules::expect_pointer): likewise + (UnifyRules::expect_param): likewise + (UnifyRules::expect_array): likewise + (UnifyRules::expect_slice): likewise + (UnifyRules::expect_fndef): likewise + (UnifyRules::expect_fnptr): likewise + (UnifyRules::expect_tuple): likewise + (UnifyRules::expect_bool): likewise + (UnifyRules::expect_char): likewise + (UnifyRules::expect_int): likewise + (UnifyRules::expect_uint): likewise + (UnifyRules::expect_float): likewise + (UnifyRules::expect_isize): likewise + (UnifyRules::expect_usize): likewise + (UnifyRules::expect_placeholder): likewise + (UnifyRules::expect_projection): likewise + (UnifyRules::expect_dyn): likewise + (UnifyRules::expect_closure): likewise + (UnifyRules::expect_const): likewise + * typecheck/rust-unify.h: new expect_const_type handler + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-intrinsic.cc (sizeof_handler): refactor types + (op_with_overflow_inner): likewise + (uninit_handler): likewise + (move_val_init_handler): likewise + * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): likewise + * typecheck/rust-hir-trait-resolve.cc: likewise + * typecheck/rust-hir-type-check-base.cc: likewise + * typecheck/rust-hir-type-check-item.cc: likewise + * typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::is_equal): likewise + * typecheck/rust-tyty-subst.cc (SubstitutionParamMapping::get_param_ty): likewise + (SubstitutionArg::get_param_mapping): likewise + (SubstitutionRef::prepare_higher_ranked_bounds): likewise + (SubstitutionRef::monomorphize): likewise + * typecheck/rust-tyty-subst.h (class BaseGeneric): new generic base + * typecheck/rust-tyty.cc (VariantDef::clone): likewise + (VariantDef::monomorphized_clone): refactor + (ADTType::is_equal): likewise + (FnType::is_equal): likewise + (ParamType::ParamType): likewise + * typecheck/rust-tyty.h (class ParamType): likewise + (class BaseGeneric): new base class impl + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-tyty.cc (ADTType::is_equal): let param::is_eq do this + (FnType::is_equal): remove whitespace + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-base.cc: check for type param + * typecheck/rust-tyty-subst.cc (SubstitutionParamMapping::SubstitutionParamMapping): + return HIR::GenericParam base class + (SubstitutionParamMapping::get_generic_param): likewise + (SubstitutionParamMapping::get_type_representation): new helper + (SubstitutionParamMapping::param_has_default_ty): check for param type + (SubstitutionParamMapping::get_default_ty): likewise + * typecheck/rust-tyty-subst.h: get the locus from the subst HIR::GenericParam now + * typecheck/rust-tyty-variance-analysis.cc (GenericTyPerCrateCtx::debug_print_solutions): + likwise + (GenericTyVisitorCtx::process_type): likewise + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-expr.cc (CompileExpr::visit): check for ADTType instead of assert + +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * checks/lints/rust-lint-unused-var.cc (check_decl): + Do not warn about unused `self` parameter. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * Make-lang.in: + * ast/rust-expression-yeast.cc (ExpressionYeast::dispatch_loops): Call DesugarWhileLet. + * ast/rust-desugar-while-let.cc: New file. + * ast/rust-desugar-while-let.h: New file. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * ast/rust-ast.cc (AttrInputMacro::operator=): Add return type. + * ast/rust-expr.h: Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-desugar-for-loops.cc: Remove functions implemented in AST::Builder. + * ast/rust-desugar-for-loops.h: Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * hir/rust-ast-lower-base.cc: Add rust_unreachable() when lowering desugared exprs. + * hir/rust-ast-lower-base.h: Mention this. + * hir/rust-ast-lower-block.h: Remove existing definitions. + * hir/rust-ast-lower-expr.cc: Likewise. + * hir/rust-ast-lower-expr.h: Likewise. + * hir/rust-ast-lower.cc: Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-desugar-question-mark.cc (DesugarQuestionMark::go): Add assertion for the + expr's type. + * ast/rust-desugar-try-block.cc (DesugarTryBlock::go): Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-desugar-for-loops.h: Adapt API and remove visitor. + * ast/rust-desugar-for-loops.cc: Likewise. + * ast/rust-expression-yeast.cc: Call DesugarForLoop. + * ast/rust-expression-yeast.h: Declare dispatch_loops function. + * rust-session-manager.cc (Session::expansion): Do not call for-loop desugar. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * hir/tree/rust-hir-expr.h (class OffsetOf): New. + * hir/tree/rust-hir-expr.cc: Define its methods. + * hir/tree/rust-hir-expr-abstract.h: Add ExprType::OffsetOf. + * hir/tree/rust-hir-full-decls.h (class OffsetOf): Declare it. + * backend/rust-compile-block.h: Add handling for OffsetOf. + * backend/rust-compile-expr.cc (CompileExpr::visit): Likewise. + * backend/rust-compile-expr.h: Likewise. + * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit): Likewise. + * checks/errors/borrowck/rust-bir-builder-expr-stmt.h (RUST_BIR_BUILDER_EXPR_H): Likewise. + * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Likewise. + * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise. + * checks/errors/borrowck/rust-function-collector.h: Likewise. + * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit): Likewise. + * checks/errors/privacy/rust-privacy-reporter.h (RUST_PRIVACY_REPORTER_H): Likewise. + * checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise. + * checks/errors/rust-const-checker.h: Likewise. + * checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit): Likewise. + * checks/errors/rust-hir-pattern-analysis.h: Likewise. + * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise. + * checks/errors/rust-unsafe-checker.h: Likewise. + * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise. + * hir/rust-hir-dump.cc (Dump::visit): Likewise. + * hir/rust-hir-dump.h: Likewise. + * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): Likewise. + * hir/tree/rust-hir-visitor.h: Likewise. + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. + * typecheck/rust-hir-type-check-expr.h (RUST_HIR_TYPE_CHECK_EXPR): Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * Make-lang.in: Compile the offset_of handler. + * lang.opt: Add -frust-assume-builtin-offset-of option. + * ast/rust-ast.h: Add has_str() for const_TokenPtr. + * expand/rust-macro-builtins.cc: Map offset_of as builtin. + * expand/rust-macro-builtins.h: Declare it. + * expand/rust-macro-expand.cc (MacroExpander::expand_invoc): Add hack for calling builtin + offset_of!(). + * resolve/rust-early-name-resolver-2.0.cc (Early::visit): Likewise. + * expand/rust-macro-builtins-offset-of.cc: New file. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast.h: Add OffsetOf expression kind. + * ast/rust-builtin-ast-nodes.h (class OffsetOf): Add node. + * ast/rust-ast.cc: Define it. + * ast/rust-ast-collector.cc: Add visitor for OffsetOf. + * ast/rust-ast-collector.h: Likewise. + * ast/rust-ast-visitor.cc: Likewise. + * ast/rust-ast-visitor.h: Likewise. + * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise. + * hir/rust-ast-lower-base.h: Likewise. + * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise. + * hir/rust-ast-lower-expr.h: Likewise. + * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise. + * resolve/rust-ast-resolve-base.h: Likewise. + * resolve/rust-early-name-resolver-2.0.cc: Likewise. + * expand/rust-derive.h: + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * rust-diagnostics.h (struct Error): Add disambiguation. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * expand/rust-macro-builtins-asm.cc (parse_format_strings): Emit an + error when expecting a comma. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * checks/errors/borrowck/rust-bir-fact-collector.h: Remove spurious + comment. + * checks/errors/rust-feature.cc: Likewise. + * util/optional.h: Likewise. + * expand/rust-token-tree-desugar.cc (TokenTreeDesugar::visit): Remove + semicolons on namespace. + * expand/rust-token-tree-desugar.h: Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * typecheck/rust-hir-type-check-base.cc + (TypeCheckBase::TypeCheckBase): Remove initialization of + resolver field. + * typecheck/rust-hir-type-check-base.h + (TypeCheckBase::resolver): Remove field. + * typecheck/rust-hir-trait-resolve.cc: Remove "options.h" + include. + (TraitResolver::resolve_path_to_trait): Assume name resolution + 2.0 is always enabled. + * typecheck/rust-hir-type-check-enumitem.cc: Remove "options.h" + include. + (TypeCheckEnumItem::visit): Assume name resolution 2.0 is always + enabled. + * typecheck/rust-hir-type-check-expr.cc: Remove "options.h" + include. + (TypeCheckExpr::visit): Assume name resolution 2.0 is always + enabled. + (TypeCheckExpr::resolve_operator_overload): Likewise. + (TypeCheckExpr::resolve_fn_trait_call): Likewise. + * typecheck/rust-hir-type-check-implitem.cc: Remove "options.h" + include. + (TypeCheckImplItem::visit): Assume name resolution 2.0 is always + enabled. + * typecheck/rust-hir-type-check-item.cc: Remove "options.h" + include. + (TypeCheckItem::visit): Assume name resolution 2.0 is always + enabled. + * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): + Likewise. + (TypeCheckExpr::resolve_root_path): Likewise. + (TypeCheckExpr::resolve_segments): Likewise. + * typecheck/rust-hir-type-check-pattern.cc: Remove "options.h" + include. + (TypeCheckPattern::visit): Assume name resolution 2.0 is always + enabled. + * typecheck/rust-hir-type-check-type.cc + (TypeCheckType::resolve_root_path): Likewise. + (ResolveWhereClauseItem::visit): Likewise. + * typecheck/rust-hir-type-check.cc: Remove "options.h" include. + (TraitItemReference::get_type_from_fn): Assume name resolution + 2.0 is always enabled. + * typecheck/rust-type-util.cc (query_type): Likewise. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * backend/rust-compile-asm.cc (get_out_expr): Return valid output from + an operand. + (CompileAsm::asm_construct_outputs): Handle every output + (get_in_expr): Return valid input from an operand. + (CompileAsm::asm_construct_inputs): Handle every input + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * expand/rust-macro-builtins-asm.cc (parse_reg_operand_inout): Parse + expressions and build split in out. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * hir/rust-hir-dump.cc (Dump::visit): Dump inline assembly fields + * hir/tree/rust-hir-expr.h: Add non const getter and avoid operand copy + from getters. + * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): Use non const + reference. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * expand/rust-macro-builtins-asm.cc (expand_inline_asm_strings): Handle + transformation for indexed positional arguments. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * rust-backend.h: New slice_index_expression function. + * rust-gcc.cc: Implementation of slice_index_expression to generate tree node for + accessing slice elements. + * backend/rust-compile-pattern.cc: Implement SlicePattern check expression & binding + compilation against SliceType scrutinee. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit(SlicePattern)): + Add new type check case for SliceType wrapped in ReferenceType. + * backend/rust-compile-pattern.cc: Adjusted the asserts accordingly for + CompilePatternCheckExpr(SlicePattern) & CompilePatternBindings(SlicePattern). + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * Make-lang.in: Compile it. + * ast/rust-expression-yeast.cc (ExpressionYeast::dispatch): Dispatch to try-block + desugar. + * ast/rust-desugar-try-block.cc: New file. + * ast/rust-desugar-try-block.h: New file. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast.h: Add the new variant. + * ast/rust-expr.h: Use it for TryExpr class. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-default-resolver.cc (DefaultResolver::visit): Add + visitor for IfLetExprConseqElse. + * resolve/rust-default-resolver.h (DefaultResolver::visit): + Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Visit a block's loop label if it + exists. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * Make-lang.in: Compile it. + * rust-session-manager.cc: Call the expression desugar dispatcher. + * ast/rust-desugar-question-mark.cc: Rework class API. + * ast/rust-desugar-question-mark.h: Likewise. + * ast/rust-expression-yeast.cc: New file. + * ast/rust-expression-yeast.h: New file. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-expr.h: Fix formatting. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Handle defered consts. + * hir/tree/rust-hir-expr.cc (AnonConst::AnonConst): Likewise. + (AnonConst::operator=): Likewise. + * hir/tree/rust-hir-expr.h: Likewise. + * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): Likewise. + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-expr.h: Add handling for deferred consts. + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. + * ast/rust-ast.cc (AnonConst::as_string): Likewise. + (ArrayType::as_string): Likewise. + * ast/rust-type.h (class ArrayType): Use AnonConst for sizes. + * parse/rust-parse-impl.h (Parser::parse_anon_const): New function. + (Parser::parse_slice_or_array_type): Call it. + * parse/rust-parse.h: Declare it. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * resolve/rust-early-name-resolver-2.0.cc (Early::resolve_glob_import): Adapt for enums. + (Early::finalize_glob_import): Likewise. + * resolve/rust-early-name-resolver-2.0.h: Likewise. + * resolve/rust-finalize-imports-2.0.cc (GlobbingVisitor::go): Likewise. + (GlobbingVisitor::visit_module_container): New function. + (GlobbingVisitor::visit_enum_container): New function. + * resolve/rust-finalize-imports-2.0.h: Declare them. + * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Insert enums as potential + containers. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * util/rust-hir-map.cc (Mappings::insert_ast_module): Rename to... + (Mappings::insert_glob_container): ...this. + (Mappings::lookup_ast_module): Rename to... + (Mappings::lookup_glob_container): ...this. + * util/rust-hir-map.h: Change declarations. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * expand/rust-cfg-strip.cc (CfgStrip::visit): Load unloaded + modules. + * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): + Assume modules have been loaded by CfgStrip. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * expand/rust-expand-visitor.cc + (ExpandVisitor::expand_inner_items): Adjust call to + expand_macro_children. + (ExpandVisitor::expand_inner_stmts): Likewise. + (ExpandVisitor::visit): Likewise. + * expand/rust-expand-visitor.h + (ExpandVisitor::expand_macro_children): Take a pointer to member + function instead of a std::function. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): do another lookup + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-ast.cc: Include "rust-macro-invoc-lexer.h". + (AttributeParser::~AttributeParser): Move function definition + here. + (AttributeParser::AttributeParser): Likewise and adjust member + initialization. + (AttributeParser::parse_meta_item_inner): Handle changes to + peek_token. + (AttributeParser::parse_literal): Likewise. + (AttributeParser::parse_simple_path_segment): Likewise. + (AttributeParser::parse_meta_item_seq): Handle changes to + AttributeParser fields. + (AttributeParser::peek_token): Move function definition here and + wrap MacroInvocLexer. + (AttributeParser::skip_token): Likewise. + * ast/rust-macro.h (class MacroInvocLexer): Forward declare. + (class Parser): Likewise. + (AttributeParser::token_stream): Remove field. + (AttributeParser::stream_pos): Likewise. + (AttributeParser::lexer): New field. + (AttributeParser::parser): Likewise. + (AttributeParser::AttributeParser): Move definition to + "rust-ast.cc". + (AttributeParser::~AttributeParser): Likewise. + (AttributeParser::peek_token): Likewise. + (AttributeParser::skip_token): Likewise. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-resolve-path.cc (ResolvePathRef::resolve): return error_mark_node + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * hir/tree/rust-hir-expr.cc (OperatorExprMeta::OperatorExprMeta): track the rhs + * hir/tree/rust-hir-expr.h: likewise + * hir/tree/rust-hir-path.h: get rid of old comments + * typecheck/rust-hir-trait-reference.cc (TraitReference::get_trait_substs): return + references instead of copy + * typecheck/rust-hir-trait-reference.h: update header + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::ResolveOpOverload): write ambigious + operator overloads to a table and try to resolve it at the end + * typecheck/rust-hir-type-check-expr.h: new static helper + * typecheck/rust-hir-type-check.h (struct DeferredOpOverload): new model to defer resolution + * typecheck/rust-typecheck-context.cc (TypeCheckContext::lookup_operator_overload): new + (TypeCheckContext::compute_ambigious_op_overload): likewise + (TypeCheckContext::compute_inference_variables): likewise + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-base.cc: check the canonical path + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * parse/rust-parse-impl.h (Parser::parse_simple_path): Be more + careful about skipping SCOPE_RESOLUTION tokens. + (Parser::parse_simple_path_segment): Allow parsing from a + starting offset. + (Parser::parse_use_tree): Handle a non-skipped SCOPE_RESOLUTION + token. + * parse/rust-parse.h (Parser::parse_simple_path_segment): Add + parameter for parsing from a starting offset. + +2025-08-05 lishin <lishin1008@gmail.com> + + * backend/rust-compile-expr.cc (CompileExpr::visit): Add a catch for const/static. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * rust-backend.h: New size_constant_expression function. + * rust-gcc.cc: Implementation of size_constant_expression function to generate tree node + for array access. + * backend/rust-compile-pattern.h: Remove empty visits for SlicePattern. + * backend/rust-compile-pattern.cc: Implement SlicePattern check expression & binding + compilation against ArrayType scrutinee. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * typecheck/rust-hir-type-check-pattern.cc(TypeCheckPattern::visit(SlicePattern)): + Implement size checking for SlicePattern when type checking against array parent + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * util/rust-attribute-values.h: Add declarations for them. + * util/rust-attributes.cc: Add definitions. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::visit): fix typo + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-casts.cc (TypeCastRules::resolve): optional emit_error flag + (TypeCastRules::check): try the simple cast rules then fallback to coercions + (TypeCastRules::check_ptr_ptr_cast): ensure the underlying's + (TypeCastRules::emit_cast_error): make this a static helper + * typecheck/rust-casts.h: new emit_error prototype + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Check for a label + before visiting it. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): track is super trait + * typecheck/rust-hir-type-bounds.h: refactor bounds scan + * typecheck/rust-hir-type-check-base.h: track from super trait + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): likewise + * typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::is_bound_satisfied_for_type): refactor + (TypeBoundsProbe::scan): likewise + (TypeBoundPredicate::apply_generic_arguments): likewise + * typecheck/rust-tyty-subst.cc: optional bounds checking on parm subst + * typecheck/rust-tyty-subst.h: likewise + * typecheck/rust-tyty.h: likewise + +2025-08-05 Marc Poulhiès <dkm@kataplop.net> + + * checks/errors/borrowck/rust-bir-place.h (LoanId::value): Make + it size_t to match Loan's base type. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * typecheck/rust-hir-type-check-pattern.cc(TypeCheckPattern::visit(LiteralPattern)): + Check LiteralPattern's type against its parent. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit(SlicePattern)): + Implement initial type checking for SlicePattern. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * ast/rust-ast-collector.cc (TokenCollector::visit): check for missing borrow + * ast/rust-expr.h: add helper + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-base.cc (HIRCompileBase::query_compile_const_expr): new wrapper + * backend/rust-compile-base.h: add prototype + * backend/rust-compile-context.cc (Context::get): singleton helper + * backend/rust-compile-context.h: likewise + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): handle infer's that can default + * rust-session-manager.cc (Session::compile_crate): create the gcc context earlier for tychk + * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::resolve_literal): const fold it + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): likewise + * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise + * typecheck/rust-tyty.cc (BaseType::monomorphized_clone): fix constructor call + (ArrayType::as_string): print capacity + (ArrayType::clone): fix constructor call + * typecheck/rust-tyty.h: track capacity + * typecheck/rust-unify.cc (UnifyRules::expect_array): check the capacities + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * resolve/rust-late-name-resolver-2.0.cc (Late::visit): New visitor. + * resolve/rust-late-name-resolver-2.0.h: Declare it. + * resolve/rust-name-resolution-context.h (enum class): New binding context. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Check that the WhileLet has a label + before visiting it. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-ast-collector.cc (TokenCollector::visit): Add visitor + for TryExpr. + * ast/rust-ast-collector.h (TokenCollector::visit): Likewise. + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. + * ast/rust-ast-visitor.h (ASTVisitor::visit): Likewise. + (DefaultASTVisitor::visit): Likewise. + * expand/rust-derive.h (DeriveVisitor::visit): Likewise. + * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise. + * hir/rust-ast-lower-base.h (ASTLoweringBase::visit): Likewise. + * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): + Likewise. + * resolve/rust-ast-resolve-base.h (ResolverBase::visit): + Likewise. + * ast/rust-ast-full-decls.h (class TryExpr): New forward class + declaration. + * ast/rust-ast.cc (TryExpr::as_string): New function. + (TryExpr::accept_vis): Likewise. + * ast/rust-expr.h (class TryExpr): New class. + * parse/rust-parse.h (Parser::parse_try_expr): New function. + * parse/rust-parse-impl.h (Parser::parse_try_expr): Likewise. + (Parser::null_denotation_not_path): Use parse_try_expr to parse + try expressions. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * expand/rust-macro-builtins-format-args.cc + (format_args_parse_arguments): Accept a RAW_STRING_LITERAL token + as the first argument. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * parse/rust-parse-impl.h: Add enum prefix. + * parse/rust-parse.h (enum ParseSelfError): Change from enum... + (enum class): To enum class. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Replace + usages of reinterpret_cast with static_cast. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Remove + override for StructStruct visitor. + * resolve/rust-late-name-resolver-2.0.h (Late::visit): Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * backend/rust-compile-context.cc (Context::Context): Remove + initialization of resolver field. + * backend/rust-compile-context.h (Context::get_resolver): Remove + function. + (Context::resolver): Remove field. + * backend/rust-compile-expr.cc (CompileExpr::visit): Assume name + resolution 2.0 is always enabled. + (CompileExpr::generate_closure_function): Likewise. + * backend/rust-compile-implitem.cc (CompileTraitItem::visit): + Likewise. + * backend/rust-compile-item.cc (CompileItem::visit): Likewise. + * backend/rust-compile-resolve-path.cc + (ResolvePathRef::resolve): Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * lang.opt (frust-name-resolution-2.0): Enable by default. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit(TuplePattern)): + Implement check expression compilation for TuplePatternItems::RANGED. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * typecheck/rust-hir-type-check-pattern.cc (visit(TuplePattern)): Fix + incorrect logic for field size checking. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-builder.cc: Remove extra include, fix new formatting. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast.h (reconstruct_vec): Pre-allocate size of vector. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * Make-lang.in: Remove object file for ASTTypeBuilder. + * ast/rust-ast-builder.h: Remove function. + * ast/rust-ast-builder.cc (Builder::new_type): Likewise. + (Builder::new_const_param): Use reconstruct_type() instead. + (Builder::new_generic_args): Likewise. + * expand/rust-derive-default.cc (DeriveDefault::visit_struct): Likewise. + (DeriveDefault::visit_tuple): Likewise. + * expand/rust-derive-eq.cc (DeriveEq::visit_tuple): Likewise. + (DeriveEq::visit_struct): Likewise. + (DeriveEq::visit_enum): Likewise. + (DeriveEq::visit_union): Likewise. + * ast/rust-ast-builder-type.cc: Removed. + * ast/rust-ast-builder-type.h: Removed. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast.h: Add reconstruct() and reconstruct_impl() for Type nodes. + * ast/rust-type.h: Implement them. + * ast/rust-macro.h: Likewise. + * ast/rust-path.h: Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast.h (reconstruct): New function for calling the `reconstruct_*_impl` method + and asserting that the new NodeId is different, and then wrap it in a unique_ptr<T>. + (reconstruct_vec): Likewise, but for vectors of unique_ptr<T> + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-forever-stack.hxx (ForeverStack::resolve_path): + Resolve final segments which point to modules. + * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): + Avoid inserting module names into ribs in the type namespace. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-late-name-resolver-2.0.cc + (visit_identifier_as_pattern): Handle is_ref and is_mut. + (Late::visit): Likewise. + * resolve/rust-name-resolution-context.cc + (BindingLayer::insert_ident): Likewise. + (BindingLayer::bind_test): Handle changes to BindingLayer + fields. + (BindingLayer::merge): Likewise and emit more error messages. + * resolve/rust-name-resolution-context.h + (struct IdentifierMode): New. + (Binding::has_expected_bindings): New field. + (Binding::set): Rename field to... + (Binding::idents): ...here and convert from a set to a map. + (Binding::Binding): Initialize has_expected_bindings. + (BindingLayer::insert_ident): Adjust parameters. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * ast/rust-expr.h: Add getter to locus field. + * ast/rust-pattern.h (tokenid_to_rangekind): Likewise. + * hir/tree/rust-hir-item.h: Likewise. + * hir/tree/rust-hir-visibility.h: Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-default-resolver.cc + (DefaultResolver::visit_extern_crate): New function. + (DefaultResolver::visit): New visitor function for ExternCrate. + * resolve/rust-default-resolver.h + (DefaultResolver::visit_extern_crate): New function. + (DefaultResolver::visit): New visitor function for ExternCrate. + * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): + Adjust ExternCrate visitor and rename to... + (TopLevel::visit_extern_crate): ...here. + * resolve/rust-toplevel-name-resolver-2.0.h (TopLevel::visit): + Remove ExternCrate visitor override. + (TopLevel::visit_extern_crate): New function. + * rust-session-manager.cc (Session::load_extern_crate): Only run + name resolution 1.0 if name resolution 2.0 is disabled. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit(TuplePattern)): + Implement type checking for ItemType::RANGED. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust-lang.cc: Move version check from C++11 to C++14. + +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * Make-lang.in: Scaffolding new rust-hir-visitor files + * hir/tree/rust-hir-visitor.h (DefaultHIRVisitor): Declare default HIR visitor + * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor): Define default HIR visitor + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * Make-lang.in (GRS_OBJS): Add rust-ggc.o. + * backend/rust-compile-base.cc + (HIRCompileBase::compile_function): Adjust call to + Backend::function. + (HIRCompileBase::compile_constant_item): Likewise and adjust + initialization of Backend::typed_identifier. + * backend/rust-compile-expr.cc (CompileExpr::visit): Adjust call + to Backend::label. + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): + Adjust initialization of Backend::typed_identifier. + * rust-backend.h: Add includes. + (Backend::GGC::Ident): Use Rust::GGC::Ident. + (struct typed_identifier): Store name as a GGC::Ident rather + than a std::string and adjust constructors. + (named_type): Take GGC::Ident/tl::optional<GGC::Ident> rather + than std::string. + (global_variable): Likewise. + (local_variable): Likewise. + (parameter_variable): Likewise. + (static_chain_variable): Likewise. + (label): Likewise. + (function): Likewise. + * rust-gcc.cc (named_type): Likewise. + (global_variable): Likewise. + (local_variable): Likewise. + (parameter_variable): Likewise. + (static_chain_variable): Likewise. + (label): Likewise. + (function): Likewise. + (function_defer_statement): Adjust call to Backend::label. + (get_identifier_from_string): Remove function. + (fill_in_fields): Handle adjustments to typed_identifier. + * util/rust-ggc.cc: New file. + * util/rust-ggc.h: New file. + +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * hir/tree/rust-hir-item.h (SelfParam::get_lifetime): Add getter + for non const lifetime object + +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * hir/tree/rust-hir-expr.h (MatchArm::get_outer_attrs): Add getter for outer attributions + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-resolve-path.cc: if this fails fall back to query compile + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-expr.cc (CompileExpr::visit): add const call check + * backend/rust-compile-item.cc (CompileItem::visit): ensure we upfront compile types where + possible + * backend/rust-compile-item.h: update header + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): make parent ctx optional + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * backend/rust-compile-pattern.cc(CompilePatternCheckExpr::visit(TupleStructPattern)): + Fix error thrown when compiling non-enum TupleStructPattern. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-default-resolver.cc (DefaultResolver::visit): + Call DefaultASTVisitor::visit even on ConstantItem instances + without expressions. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-unify.cc (UnifyRules::expect_fnptr): add unify rules + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-trait-reference.cc (TraitReference::on_resolved): ensure associated + types are done first + * typecheck/rust-hir-type-check-type.cc: Update call site. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-tyty-bounds.cc: Check super traits for type bindings. + * typecheck/rust-tyty.h: Add helper methods for bound checking. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-bounds.h: Rename method. + * typecheck/rust-tyty-bounds.cc: Refactor marker trait assembly + and add proper Fn trait handling for function types. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-dot-operator.cc: Major refactoring and cleanup. + * typecheck/rust-hir-dot-operator.h: Add new helper methods. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-trait-resolve.cc: Add cyclical projection + protection. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check-expr.cc: Look at bounds behind + references. + * typecheck/rust-hir-type-check-expr.h: Add helper method. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust-session-manager.cc (Session::compile_crate): Move + AST desugaring to... + (Session::expansion): ...here and add a final TopLevel pass + afterwards. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): check for has_expr + * hir/rust-hir-dump.cc (Dump::visit): likewise + * hir/tree/rust-hir-item.h: add has_expr helper + * resolve/rust-ast-resolve-item.cc (ResolveItem::visit): check for has_expr + * resolve/rust-ast-resolve-stmt.h: likewise + * typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): likewise + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Add + visitor for ExternCrate. + * hir/rust-ast-lower-item.h (ASTLoweringItem::visit): Likewise. + * rust-session-manager.cc (Session::load_extern_crate): Avoid + lowering or type resolving external crates here. + * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): + Add visitor for ExternCrate. + * typecheck/rust-hir-type-check-item.h (TypeCheckItem::visit): + Replace empty definition with a declaration. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-tyty.cc (ParamType::handle_substitions): make this consistent + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * resolve/rust-late-name-resolver-2.0.cc (Late::visit(IdentifierPattern)): + Remove redundant subpattern check. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * backend/rust-compile-pattern.cc: Add support for IdentifierPattern's + subpattern under CompilePatternBindings. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * resolve/rust-ast-resolve-pattern.cc: Implement name resolution for + IdentifierPattern's subpattern. + * resolve/rust-late-name-resolver-2.0.cc: Ditto, but for nr2. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * ast/rust-ast-collector.cc: Rename get_pattern_to_bind to get_subpattern + * ast/rust-ast-visitor.cc: Ditto. + * ast/rust-pattern.h: Ditto. + * expand/rust-cfg-strip.cc: Ditto. + * hir/rust-ast-lower-pattern.cc: Ditto. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-default-resolver.cc (DefaultResolver::visit): + Adjust scoping of trait definitions and their generic + parameters. + * resolve/rust-forever-stack.hxx (ForeverStack::get): Prevent + lookups inside TraitOrImpl ribs. + (ForeverStack::resolve_segments): Prevent lookups of the first + segment inside TraitOrImpl ribs. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * hir/rust-hir-dump.cc: Change pattern dumps to use visit_field. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive.cc: Fix formatting after fork update. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-cmp-common.cc (EnumMatchBuilder::tuple): Create two different + variant paths. + (EnumMatchBuilder::strukt): Likewise. + * expand/rust-derive-cmp-common.h: Change API. + * expand/rust-derive-ord.cc (DeriveOrd::visit_enum): Use new EnumMatchBuilder API. + * expand/rust-derive-partial-eq.cc (DerivePartialEq::visit_enum): Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-ord.cc (DeriveOrd::make_cmp_arms): Use new make_equal function. + (DeriveOrd::make_equal): New function. + (DeriveOrd::recursive_match): Handle the unit struct/tuple case. + * expand/rust-derive-ord.h: Declare make_equal. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-ord.cc (DeriveOrd::cmp_call): Use references. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-ord.cc (DeriveOrd::make_cmp_arms): Fix condition. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-ord.cc: Finish implementation for enums. + * expand/rust-derive-ord.h: Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-partial-eq.cc (DerivePartialEq::eq_fn): Change signature. + (DerivePartialEq::visit_tuple): Use new eq_fn API. + (DerivePartialEq::visit_struct): Likewise. + (DerivePartialEq::visit_enum): Implement proper discriminant comparison. + * expand/rust-derive-partial-eq.h: Change eq_fn signature. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-cmp-common.h (class EnumMatchBuilder): New helper class. + * expand/rust-derive-cmp-common.cc (EnumMatchBuilder::tuple): New function. + (EnumMatchBuilder::strukt): New function. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-builder.h: Put `loc` member in public. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-ord.cc (DeriveOrd::cmp_call): New function. + (DeriveOrd::recursive_match): Use it. + (DeriveOrd::visit_enum): Likewise. + * expand/rust-derive-ord.h: Declare it. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-hash.cc (DeriveHash::visit_enum): Use new APIs. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-builder.cc (Builder::discriminant_value): New function. + * ast/rust-ast-builder.h: Declare it. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-ord.cc (is_last): Remove. + (DeriveOrd::visit_tuple): Fix implementation. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-cmp-common.cc (SelfOther::indexes): Fix formatting. + (SelfOther::fields): Make iterator const. + * expand/rust-derive-cmp-common.h (struct SelfOther): New declaration for indexes. + * expand/rust-derive-partial-eq.cc (DerivePartialEq::visit_tuple): Use the new API. + (DerivePartialEq::visit_struct): Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-ord.cc (DeriveOrd::make_cmp_arms): New function. + (is_last): Likewise. + (recursive_match): Likewise. + (DeriveOrd::recursive_match): Likewise. + (DeriveOrd::visit_struct): Add proper implementation. + (DeriveOrd::visit_union): Likewise. + * expand/rust-derive-ord.h: Declare these new functions. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-partial-eq.cc (DerivePartialEq::tuple_indexes): Remove. + (DerivePartialEq::field_acccesses): Remove. + (DerivePartialEq::visit_tuple): Use new API. + (DerivePartialEq::visit_struct): Likewise. + * expand/rust-derive-partial-eq.h: Remove declarations. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-cmp-common.cc: New file. + * expand/rust-derive-cmp-common.h: New file. + * Make-lang.in: Compile them. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-builder.cc (Builder::block): New function. + (Builder::match_case): Likewise. + * ast/rust-ast-builder.h: Declare them. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-builder.cc (Builder::new_const_param): New function. + * ast/rust-ast-builder.h (vec): New function for creating 3 elts vector. + * expand/rust-derive.cc: Use the new_const_param builder. + * ast/rust-path.h: Add get_default_value() method. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * Make-lang.in: Compile it. + * expand/rust-derive.cc (DeriveVisitor::derive): Call them. + * expand/rust-derive-ord.cc: New file. + * expand/rust-derive-ord.h: New file. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-clone.h: Add missing override qualifiers to DeriveVisitor methods. + * expand/rust-derive-copy.h: Likewise. + * expand/rust-derive-eq.h: Likewise. + * expand/rust-derive-hash.h: Likewise. + * expand/rust-derive-partial-eq.h: Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * resolve/rust-rib.h: Add missing switch cases. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-type-util.cc (query_type): early return. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): reuse GCC's build_array_type + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-late-name-resolver-2.0.cc + (visit_identifier_as_pattern): Make sure to map identifiers + inside or-bindings to prior identifiers. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * ast/rust-ast-collector.cc: Rename to_bind to subpattern. + * ast/rust-ast-visitor.cc: Ditto. + * ast/rust-pattern.cc: Ditto. + * ast/rust-pattern.h: Ditto. + * backend/rust-compile-pattern.cc: Ditto. + * expand/rust-cfg-strip.cc: Ditto. + * hir/rust-ast-lower-pattern.cc: Ditto. + * hir/rust-hir-dump.cc: Ditto. + * hir/tree/rust-hir-pattern.h: Ditto. + * hir/tree/rust-hir.cc: Ditto. + * typecheck/rust-hir-type-check-pattern.cc: Ditto. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * backend/rust-compile-pattern.cc: Add CheckExpr compilation for + IdentifierPattern with subpattern. + * backend/rust-compile-pattern.h: Modify IdentifierPattern's + visit func to support the above. + * typecheck/rust-hir-type-check-pattern.cc: Add typechecking + support for the changes above. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-default-resolver.cc + (DefaultResolver::visit_closure_params): New member function + definition. + (DefaultResolver::visit): New visiting function definition for + ClosureExpr called from visiting functions for ClosureExprInner + and ClosureExprInnerTyped. + * resolve/rust-default-resolver.h + (DefaultResolver::visit_closure_params): New member function + declaration. + (DefaultResolver::visit): New visiting function declaration for + ClosureExpr. + * resolve/rust-late-name-resolver-2.0.cc (add_captures): Remove + function. + (Late::visit): New visiting function definition for ClosureExpr, + remove visiting function definitions for ClosureExprInner and + ClosureExprInnerTyped. + (Late::visit_closure_params): New member function definition. + * resolve/rust-late-name-resolver-2.0.h (Late::visit): New + visiting function declaration for ClosureExpr, remove visiting + function declarations for ClosureExprInner and + ClosureExprInnerTyped. + (Late::visit_closure_params): New member function declaration. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-forever-stack.hxx (ForeverStack::resolve_path): + Handle single segment paths "crate", "self", and "super". + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Use + visit_identifier_as_pattern to handle IdentifierPattern and + StructPatternFieldIdent. + (visit_identifier_as_pattern): New function. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-expr.h (ClosureExpr::get_definition_expr): New + virtual member function. + (ClosureExprInner::get_definition_expr): Add override specifier. + (ClosureExprInnerTyped::get_definition_block): Rename to... + (ClosureExprInnerTyped::get_definition_expr): ...here and add + override specifier. + * ast/rust-ast-collector.cc (TokenCollector::visit): Handle + rename of ClosureExprInnerTyped::get_definition_block to + ClosureExprInnerTyped::get_definition_expr. + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. + * expand/rust-cfg-strip.cc (CfgStrip::visit): Likewise. + * expand/rust-expand-visitor.cc (ExpandVisitor::visit): + Likewise. + * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise. + * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): + Likewise. + * resolve/rust-late-name-resolver-2.0.cc (Late::visit): + Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * backend/rust-compile-base.cc + (HIRCompileBase::compile_function): Since canonical paths + returned from nr2.0 now include the crate name, avoid prepending + the crate name again. + * backend/rust-compile-implitem.cc (CompileTraitItem::visit): + Use NameResolutionContext::to_canonical_path instead of + ForeverStack::to_canonical_path. + * backend/rust-compile-item.cc (CompileItem::visit): Likewise. + * typecheck/rust-hir-type-check-enumitem.cc + (TypeCheckEnumItem::visit): Likewise. + * typecheck/rust-hir-type-check-implitem.cc + (TypeCheckImplItem::visit): Likewise. + * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): + Likewise. + * typecheck/rust-hir-type-check.cc + (TraitItemReference::get_type_from_fn): Likewise. + * resolve/rust-default-resolver.cc (DefaultResolver::visit): Add + Crate and EnumItem instance visitors, handle canonical path + context scoping. + * resolve/rust-default-resolver.h (DefaultResolver::visit): Add + Crate and EnumItem instance visitors. + * resolve/rust-early-name-resolver-2.0.cc (Early::go): Visit + instances of Crate using the virtual member function visit. + * resolve/rust-forever-stack.h + (ForeverStack::to_canonical_path): Remove function declaration. + * resolve/rust-forever-stack.hxx + (ForeverStack::to_canonical_path): Remove function definition. + * resolve/rust-late-name-resolver-2.0.cc (Late::go): Visit + instances of Crate using the virtual member function visit. + * resolve/rust-name-resolution-context.cc + (CanonicalPathRecordCrateRoot::as_path): New function definition. + (CanonicalPathRecordNormal::as_path): Likewise. + (CanonicalPathRecordLookup::as_path): Likewise. + (CanonicalPathRecordImpl::as_path): Likewise. + (CanonicalPathRecordTraitImpl::as_path): Likewise. + (NameResolutionContext::NameResolutionContext): Initialize + member variable canonical_ctx. + * resolve/rust-name-resolution-context.h: Include "rust-item.h". + (class NameResolutionContext): Forward declare class. + (class CanonicalPathRecord): New class. + (class CanonicalPathRecordWithParent): Likewise. + (class CanonicalPathRecordCrateRoot): Likewise. + (class CanonicalPathRecordNormal): Likewise. + (class CanonicalPathRecordLookup): Likewise. + (class CanonicalPathRecordImpl): Likewise. + (class CanonicalPathRecordTraitImpl): Likewise. + (class CanonicalPathCtx): Likewise. + (NameResolutionContext::canonical_ctx): New member variable. + (NameResolutionContext::to_canonical_path): New member function. + * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::go): + Visit instances of Crate with the virtual member function visit. + (TopLevel::visit): Handle canonical path context scoping for + external crates, use DefaultResolver::visit when visiting + instances of StructStruct. + * util/rust-canonical-path.h (CanonicalPath::new_seg): Take path + parameter by-value, as a duplicate instance will be constructed + regardless. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * hir/rust-ast-lower-pattern.cc: Lower of IdentifierPattern's to_bind to HIR. + * hir/rust-hir-dump.cc: Update IdentifierPattern's dump to properly show to_bind's full + full properties. + +2025-08-05 Vishruth-Thimmaiah <vishruththimmaiah@gmail.com> + + * lex/rust-lex.cc (Lexer::parse_raw_byte_string): + Fix infinite looping when a raw byte string is not terminated. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-default-resolver.cc (DefaultResolver::visit): Use + visit_impl_type to visit the self types of impl blocks. + * resolve/rust-default-resolver.h + (DefaultResolver::visit_impl_type): New member function + declaration. + * resolve/rust-late-name-resolver-2.0.cc (Late::Late): + Initialize member variable block_big_self. + (Late::visit_impl_type): New member function definition. + (Late::visit): Check for Self while inside impl block self + types. + * resolve/rust-late-name-resolver-2.0.h (Late::visit_impl_type): + New member function. + (Late::block_big_self): New member variable. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-forever-stack.h + (enum ResolutionMode): New. + (ForeverStack::get): Add a private overload that takes a + starting node as a parameter. + (ForeverStack::resolve_path): Replace boolean parameter + has_opening_scope_resolution with ResolutionMode parameter mode. + * resolve/rust-forever-stack.hxx + (ForeverStack::resolve_path): Likewise. + (ForeverStack::get): Add a private overload that takes a + starting node as a parameter. + * resolve/rust-late-name-resolver-2.0.cc + (Late::visit): Add Visibility visitor. + * resolve/rust-late-name-resolver-2.0.h + (Late::visit): Likewise. + * resolve/rust-name-resolution-context.h + (NameResolutionContext::resolve_path): Rework overloading a bit + and accept ResolutionMode parameter. + +2025-08-05 Vishruth-Thimmaiah <vishruththimmaiah@gmail.com> + + * parse/rust-parse.cc (Rust::extract_module_path): + Handle empty or whitespace-only path attributes. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-ast-collector.cc (TokenCollector::visit): Handle + changed type of ConstantItem::identifier. + * ast/rust-ast.cc (ConstantItem::as_string): Likewise. + * ast/rust-ast.h (operator const std::string &): New member + function. + * ast/rust-item.h (ConstantItem::identifier): Change type from + std::string to Identifier. + (ConstantItem::ConstantItem): Handle changed type of identifier + field. + (ConstantItem::is_unnamed): Likewise. + (ConstantItem::get_identifier): Likewise. + * hir/rust-ast-lower-extern.h (ASTLoweringExternItem::visit): + Avoid discarding location of wildcard patterns. + * lex/rust-token.cc: Include "rust-ast.h". + (Token::make_identifier): Add overload accepting an Identifier + instance. + * lex/rust-token.h (class Identifier): Add forward declaration + in order to... + (Token::make_identifier): ...declare an overload for this static + member function. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * hir/tree/rust-hir-expr.h: New classes. + * hir/tree/rust-hir-full-decls.h: Likewise. + * hir/tree/rust-hir.cc: Handle AnonConst and ConstBlock. + * backend/rust-compile-block.cc: Likewise. + * backend/rust-compile-block.h: Likewise. + * backend/rust-compile-expr.cc (CompileExpr::visit): Likewise. + * backend/rust-compile-expr.h: Likewise. + * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit): Likewise. + * checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Likewise. + * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Likewise. + * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise. + * checks/errors/borrowck/rust-function-collector.h: Likewise. + * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit): Likewise. + * checks/errors/privacy/rust-privacy-reporter.h: Likewise. + * checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise. + * checks/errors/rust-const-checker.h: Likewise. + * checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit): Likewise. + * checks/errors/rust-hir-pattern-analysis.h: Likewise. + * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise. + * checks/errors/rust-unsafe-checker.h: Likewise. + * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise. + (translate_operand_out): Likewise. + (translate_operand_inout): Likewise. + (translate_operand_const): Likewise. + * hir/rust-ast-lower-expr.h: Likewise. + * hir/rust-hir-dump.cc (Dump::visit): Likewise. + * hir/rust-hir-dump.h: Likewise. + * hir/tree/rust-hir-expr-abstract.h: Likewise. + * hir/tree/rust-hir-expr.cc (AnonConst::AnonConst): Likewise. + (AnonConst::operator=): Likewise. + (ConstBlock::ConstBlock): Likewise. + (ConstBlock::operator=): Likewise. + * hir/tree/rust-hir-visitor.h: + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. + (typecheck_inline_asm_operand): Likewise. + * typecheck/rust-hir-type-check-expr.h: Likewise. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * parse/rust-parse-impl.h (Parser::parse_const_block_expr): New function. + * parse/rust-parse.h: Declare it. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-expr.h: Declare AnonConst and ConstBlock and use them. + * ast/rust-ast-full-decls.h: Likewise. + * ast/rust-ast.cc: Add implementation for AnonConst and ConstBlock. + * ast/rust-ast.h: Likewise. + * ast/rust-ast-collector.cc (TokenCollector::visit): Likewise. + * ast/rust-ast-collector.h: Likewise. + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. + * ast/rust-ast-visitor.h: Likewise. + * expand/rust-derive.h: Likewise. + * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise. + * hir/rust-ast-lower-base.h: Likewise. + * hir/rust-ast-lower-expr.cc (translate_operand_const): Likewise. + * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise. + * resolve/rust-ast-resolve-base.h: Likewise. + * resolve/rust-ast-resolve-expr.h: Likewise. + * resolve/rust-ast-resolve-expr.cc: Likewise. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-coercion.cc (TypeCoercionRules::coerce_unsized): dont emit error here + * typecheck/rust-unify.cc (UnifyRules::resolve_subtype): new helper to handle emit error + (UnifyRules::expect_adt): call resolve_subtype + (UnifyRules::expect_reference): likewise + (UnifyRules::expect_pointer): likewise + (UnifyRules::expect_array): likewise + (UnifyRules::expect_slice): likewise + (UnifyRules::expect_fndef): likewise + (UnifyRules::expect_fnptr): likewise + (UnifyRules::expect_tuple): likewise + (UnifyRules::expect_closure): likewise + (UnifyRules::expect_opaque): likeiwse + * typecheck/rust-unify.h: add new helper to header + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-default-resolver.cc + (DefaultResolver::visit_if_let_patterns): New function + definition. + (DefaultResolver::visit): New IfLetExpr visitor definition. + * resolve/rust-default-resolver.h + (DefaultResolver::visit_if_let_patterns): New function + declaration. + (DefaultResolver::visit): New IfLetExpr visitor declaration. + * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Remove + IfLetExpr visitor definition. + (Late::visit_if_let_patterns): New function definition. + * resolve/rust-late-name-resolver-2.0.h (Late::visit): Remove + IfLetExpr visitor declaration. + (Late::visit_if_let_patterns): New function declaration. + * resolve/rust-name-resolution-context.h (BindingSource::IfLet): + New enumerator. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): we need to resolve the + underlying type + * typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): just clone + * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): + ensure we monomphize to get the underlying + * typecheck/rust-tyty.cc (BaseType::destructure): handle opaque types + (OpaqueType::resolve): this is much simpler now + (OpaqueType::handle_substitions): no longer needed + * typecheck/rust-tyty.h: update header + * typecheck/rust-unify.cc (UnifyRules::expect_opaque): unify rules for opaque + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * backend/rust-compile-type.cc (TyTyResolveCompile::visit): use get_name + * typecheck/rust-tyty.cc (TupleType::get_name): likewise + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::check_base_type_privacy): + no need for unreachable here + * typecheck/rust-unify.cc (UnifyRules::commit): dont clone infer vars + (UnifyRules::expect_inference_variable): likewise + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * typecheck/rust-hir-type-check.h: new function + * typecheck/rust-typecheck-context.cc (TypeCheckContext::compute_inference_variables): + call the new helper + (TypeCheckContext::compute_infer_var): refactored code + +2025-08-05 Tom Schollenberger <tss2344@g.rit.edu> + + * resolve/rust-early-name-resolver-2.0.cc (Early::visit_attributes): rust_assert to if + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * parse/rust-parse-impl.h (Parser::parse_expr_stmt): Avoid + reference binding and remove std::move in return statements. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-ast-visitor.cc + (DefaultASTVisitor::visit): Only visit the path of an instance + of Visibility if the instance has a path. + * ast/rust-ast.h + (SimplePath::SimplePath): Make sure constructors are explicit. + * resolve/rust-early-name-resolver-2.0.cc + (Early::visit_attributes): Pass entire paths to + NameResolutionContext::resolve_path. + (Early::visit): Likewise and avoid copying a path. + * resolve/rust-forever-stack.hxx + (ForeverStack::resolve_path): Assert that at least one path + segment has been passed in. + +2025-08-05 Marc Poulhiès <dkm@kataplop.net> + + * rust-attribs.cc (handle_hot_attribute): Remove clang-format comment. + +2025-08-05 Marc Poulhiès <dkm@kataplop.net> + + * ast/rust-ast-builder-type.cc (ASTTypeBuilder::visit): Reindent. + * ast/rust-ast-builder.cc (Builder::new_generic_args): Likewise. + * ast/rust-ast-collector.cc (TokenCollector::visit): Likewise. + * ast/rust-ast-dump.h (debug): Likewise. + * ast/rust-ast-formatting.h (indent_spaces): Likewise. + (get_string_in_delims): Likewise. + (get_mode_dump_desc): Likewise. + (append_attributes): Likewise. + (unquote_string): Likewise. + * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. + * ast/rust-ast.cc (Attribute::get_traits_to_derive): Likewise. + (UseTreeGlob::as_string): Likewise. + (UseTreeList::as_string): Likewise. + (AttributeParser::parse_path_meta_item): Likewise. + (FormatArgs::set_outer_attrs): Likewise. + * ast/rust-ast.h (operator<<): Likewise. + * ast/rust-cond-compilation.h: Likewise. + * ast/rust-desugar-apit.cc: Likewise. + * ast/rust-fmt.h (collect_pieces): Likewise. + (clone_pieces): Likewise. + * ast/rust-pattern.h (tokenid_to_rangekind): Likewise. + * backend/rust-compile-context.cc (Context::type_hasher): Likewise. + * backend/rust-compile-expr.cc (CompileExpr::visit): Likewise. + * backend/rust-compile-intrinsic.cc (get_identifier): Likewise. + (offset_handler): Likewise. + (sizeof_handler): Likewise. + (transmute_handler): Likewise. + (rotate_handler): Likewise. + (wrapping_op_handler_inner): Likewise. + (op_with_overflow_inner): Likewise. + (uninit_handler): Likewise. + (move_val_init_handler): Likewise. + (assume_handler): Likewise. + (discriminant_value_handler): Likewise. + (variant_count_handler): Likewise. + (prefetch_data_handler): Likewise. + (atomic_store_handler_inner): Likewise. + (atomic_load_handler_inner): Likewise. + (unchecked_op_inner): Likewise. + (copy_handler_inner): Likewise. + (expect_handler_inner): Likewise. + (try_handler_inner): Likewise. + * backend/rust-compile-pattern.cc (compile_range_pattern_bound): Likewise. + (CompilePatternCheckExpr::visit): Likewise. + (CompilePatternBindings::visit): Likewise. + (CompilePatternLet::visit): Likewise. + * backend/rust-compile-var-decl.h: Likewise. + * backend/rust-constexpr.cc (verify_constant): Likewise. + (find_array_ctor_elt): Likewise. + (array_index_cmp): Likewise. + (potential_constant_expression_1): Likewise. + (unshare_constructor): Likewise. + (maybe_save_constexpr_fundef): Likewise. + (returns): Likewise. + (breaks): Likewise. + (continues): Likewise. + (switches): Likewise. + (constant_value_1): Likewise. + (decl_constant_value): Likewise. + (non_const_var_error): Likewise. + (eval_constant_expression): Likewise. + (constexpr_fn_retval): Likewise. + (eval_store_expression): Likewise. + (eval_call_expression): Likewise. + (eval_binary_expression): Likewise. + (get_function_named_in_call): Likewise. + (eval_statement_list): Likewise. + (extract_string_elt): Likewise. + (eval_conditional_expression): Likewise. + (eval_bit_field_ref): Likewise. + (eval_loop_expr): Likewise. + (eval_switch_expr): Likewise. + (eval_unary_expression): Likewise. + (get_or_insert_ctor_field): Likewise. + (eval_and_check_array_index): Likewise. + * backend/rust-constexpr.h (maybe_save_constexpr_fundef): Likewise. + * backend/rust-mangle-v0.cc (v0_path): Likewise. + (v0_complex_type_prefix): Likewise. + * backend/rust-mangle.h (legacy_mangle_item): Likewise. + (v0_mangle_item): Likewise. + * backend/rust-tree.cc (convert_to_void): Likewise. + (find_parameter_packs_r): Likewise. + (rs_tree_equal): Likewise. + (publicly_uniquely_derived_p): Likewise. + (instantiation_dependent_expression_p): Likewise. + (type_has_nontrivial_copy_init): Likewise. + (is_normal_capture_proxy): Likewise. + (is_bitfield_expr_with_lowered_type): Likewise. + (undeduced_auto_decl): Likewise. + (require_deduced_type): Likewise. + (gt_pch_nx): Likewise. + (lvalue_kind): Likewise. + * backend/rust-tree.h (LANG_DECL_MIN_CHECK): Likewise. + (LANG_DECL_FN_CHECK): Likewise. + (LANG_DECL_NS_CHECK): Likewise. + (LANG_DECL_PARM_CHECK): Likewise. + (LANG_DECL_DECOMP_CHECK): Likewise. + (resort_type_member_vec): Likewise. + (convert_to_void): Likewise. + (mark_discarded_use): Likewise. + (mark_exp_read): Likewise. + (mark_use): Likewise. + (mark_rvalue_use): Likewise. + (mark_lvalue_use): Likewise. + (mark_lvalue_use_nonread): Likewise. + (convert_from_reference): Likewise. + (maybe_warn_nodiscard): Likewise. + (expr_loc_or_loc): Likewise. + (expr_loc_or_input_loc): Likewise. + (get_fndecl_from_callee): Likewise. + (pointer_offset_expression): Likewise. + (is_empty_class): Likewise. + (is_really_empty_class): Likewise. + (rs_type_quals): Likewise. + (init_modules): Likewise. + (lookup_add): Likewise. + (ovl_make): Likewise. + (struct c_fileinfo): Likewise. + (get_fileinfo): Likewise. + (cxx_make_type): Likewise. + (build_cplus_array_type): Likewise. + (comptypes): Likewise. + (rs_build_qualified_type_real): Likewise. + (vector_targets_convertible_p): Likewise. + (get_class_binding_direct): Likewise. + (lang_check_failed): Likewise. + (check_for_uninitialized_const_var): Likewise. + (cp_fold_maybe_rvalue): Likewise. + (fold_offsetof): Likewise. + (fold_non_dependent_expr): Likewise. + (in_immediate_context): Likewise. + (cxx_mark_addressable): Likewise. + (decl_constant_value): Likewise. + (is_class_type): Likewise. + (fold_builtin_is_pointer_inverconvertible_with_class): Likewise. + (c_common_type_for_mode): Likewise. + (next_common_initial_seqence): Likewise. + (fold_builtin_is_corresponding_member): Likewise. + (maybe_constant_value): Likewise. + (rs_walk_subtrees): Likewise. + (make_tree_vector): Likewise. + (release_tree_vector): Likewise. + (location_of): Likewise. + (maybe_constant_init): Likewise. + (explain_invalid_constexpr_fn): Likewise. + (literal_type_p): Likewise. + (maybe_constexpr_fn): Likewise. + (fold_non_dependent_init): Likewise. + * checks/errors/borrowck/polonius/rust-polonius.h (polonius_run): Likewise. + (FFIVector__new): Likewise. + (FFIVector__new_vec_pair): Likewise. + (FFIVector__new_vec_triple): Likewise. + (FFIVector__push): Likewise. + (FFIVector__push_vec_triple): Likewise. + * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc + (ExprStmtBuilder::visit): Likewise. + * checks/errors/borrowck/rust-bir-builder-pattern.cc + (PatternBindingBuilder::visit): Likewise. + * checks/errors/borrowck/rust-bir-dump.cc (Dump::visit): Likewise. + * checks/errors/borrowck/rust-bir-fact-collector.h (points): Likewise. + * checks/errors/borrowck/rust-bir-place.h: Likewise. + * checks/errors/borrowck/rust-bir-visitor.h: Likewise. + * checks/errors/privacy/rust-privacy-check.cc (saw_errors): Likewise. + * checks/errors/privacy/rust-privacy-ctx.h (rust_privacy_ctx_test): Likewise. + * checks/errors/privacy/rust-privacy-reporter.cc + (PrivacyReporter::check_for_privacy_violation): Likewise. + (PrivacyReporter::check_base_type_privacy): Likewise. + (PrivacyReporter::visit): Likewise. + * checks/errors/privacy/rust-reachability.cc (ReachabilityVisitor::visit): Likewise. + * checks/errors/privacy/rust-visibility-resolver.cc + (VisibilityResolver::resolve_visibility): Likewise. + * checks/errors/rust-hir-pattern-analysis.cc (Constructor::is_covered_by): Likewise. + (PlaceInfo::specialize): Likewise. + (WitnessPat::to_string): Likewise. + (WitnessMatrix::apply_constructor): Likewise. + (lower_pattern): Likewise. + (lower_tuple_pattern): Likewise. + (lower_struct_pattern): Likewise. + * checks/errors/rust-hir-pattern-analysis.h (check_match_usefulness): Likewise. + * expand/rust-cfg-strip.cc (CfgStrip::maybe_strip_generic_args): Likewise. + * expand/rust-derive-eq.cc (DeriveEq::visit_enum): Likewise. + * expand/rust-derive.cc: Likewise. + * expand/rust-expand-format-args.cc (expand_format_args): Likewise. + * expand/rust-expand-visitor.h (is_derive): Likewise. + (is_builtin): Likewise. + * expand/rust-macro-builtins-asm.cc (expand_inline_asm_strings): Likewise. + * expand/rust-macro-builtins-asm.h (parse_asm): Likewise. + (check_identifier): Likewise. + (check_and_set): Likewise. + (parse_label): Likewise. + (parse_llvm_outputs): Likewise. + (parse_llvm_inputs): Likewise. + (parse_llvm_clobbers): Likewise. + (parse_llvm_options): Likewise. + * expand/rust-macro-builtins-helpers.h (make_macro_path_str): Likewise. + (make_token): Likewise. + (make_string): Likewise. + (macro_end_token): Likewise. + (parse_single_string_literal): Likewise. + (source_relative_path): Likewise. + (load_file_bytes): Likewise. + * expand/rust-macro-expand.cc (MacroExpander::match_fragment): Likewise. + (MacroExpander::match_matcher): Likewise. + (MacroExpander::match_n_matches): Likewise. + * expand/rust-macro-substitute-ctx.cc (SubstituteCtx::substitute_token): Likewise. + * expand/rust-proc-macro.h (load_macros): Likewise. + (generate_proc_macro_decls_symbol): Likewise. + * hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_generic_args): Likewise. + (ASTLoweringBase::lower_range_pattern_bound): Likewise. + * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Likewise. + * hir/rust-ast-lower-pattern.cc (ASTLoweringPattern::visit): Likewise. + * hir/rust-ast-lower.h (struct_field_name_exists): Likewise. + (translate_visibility): Likewise. + * hir/rust-hir-dump.cc (Dump::visit): Likewise. + * hir/rust-hir-dump.h (debug): Likewise. + * hir/tree/rust-hir.cc (UseTreeGlob::as_string): Likewise. + (UseTreeList::as_string): Likewise. + * lex/rust-lex.cc (Lexer::parse_escape): Likewise. + (Lexer::parse_utf8_escape): Likewise. + * lex/rust-lex.h (rust_input_source_test): Likewise. + * lex/rust-token.cc (RS_TOKEN_KEYWORD_2015): Likewise. + * lex/rust-token.h (get_token_description): Likewise. + (token_id_to_str): Likewise. + (token_id_is_keyword): Likewise. + (token_id_keyword_string): Likewise. + (get_type_hint_string): Likewise. + (nfc_normalize_token_string): Likewise. + * metadata/rust-export-metadata.cc (PublicInterface::write_to_path): Likewise. + * metadata/rust-import-archive.cc: Likewise. + * metadata/rust-imports.h (add_search_path): Likewise. + * parse/rust-cfg-parser.h (parse_cfg_option): Likewise. + (rust_cfg_parser_test): Likewise. + * parse/rust-parse-impl.h (Parser::skip_generics_right_angle): Likewise. + (Parser::parse_attr_input): Likewise. + (Parser::parse_macro_match): Likewise. + (Parser::parse_visibility): Likewise. + (Parser::parse_module): Likewise. + (Parser::parse_use_tree): Likewise. + (Parser::parse_generic_param): Likewise. + (Parser::parse_struct): Likewise. + (Parser::parse_enum_item): Likewise. + (Parser::parse_inherent_impl_item): Likewise. + (Parser::parse_external_item): Likewise. + (Parser::parse_generic_arg): Likewise. + (Parser::parse_type_path_segment): Likewise. + (Parser::parse_expr_stmt): Likewise. + (Parser::parse_if_expr): Likewise. + (Parser::parse_if_let_expr): Likewise. + (Parser::parse_type): Likewise. + (Parser::parse_for_prefixed_type): Likewise. + (Parser::parse_slice_or_array_type): Likewise. + (Parser::parse_type_no_bounds): Likewise. + (Parser::parse_range_pattern_bound): Likewise. + (Parser::parse_pattern_no_alt): Likewise. + (Parser::parse_grouped_or_tuple_pattern): Likewise. + (Parser::parse_ident_leading_pattern): Likewise. + (Parser::parse_tuple_struct_items): Likewise. + (Parser::parse_stmt_or_expr): Likewise. + (Parser::parse_struct_expr_field): Likewise. + (Parser::null_denotation): Likewise. + (Parser::left_denotation): Likewise. + (Parser::parse_closure_expr_pratt): Likewise. + * parse/rust-parse.cc (peculiar_fragment_match_compatible): Likewise. + (is_match_compatible): Likewise. + * parse/rust-parse.h (extract_module_path): Likewise. + (is_match_compatible): Likewise. + * resolve/rust-ast-resolve-expr.cc (translate_operand): Likewise. + * resolve/rust-ast-resolve-item.cc (flatten_glob): Likewise. + (flatten_rebind): Likewise. + (flatten_list): Likewise. + (flatten): Likewise. + * resolve/rust-ast-resolve-item.h (rust_simple_path_resolve_test): Likewise. + * resolve/rust-ast-resolve-pattern.cc (PatternDeclaration::visit): Likewise. + (resolve_range_pattern_bound): Likewise. + * resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): Likewise. + (ResolveTypeToCanonicalPath::visit): Likewise. + * resolve/rust-ast-resolve.cc (saw_errors): Likewise. + * resolve/rust-early-name-resolver-2.0.cc (Early::finalize_rebind_import): Likewise. + * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise. + * resolve/rust-toplevel-name-resolver-2.0.cc (flatten_glob): Likewise. + * rust-backend.h (init): Likewise. + (debug): Likewise. + (get_identifier_node): Likewise. + (wchar_type): Likewise. + (get_pointer_size): Likewise. + (raw_str_type): Likewise. + (integer_type): Likewise. + (float_type): Likewise. + (pointer_type): Likewise. + (reference_type): Likewise. + (immutable_type): Likewise. + (function_type): Likewise. + (function_type_variadic): Likewise. + (function_ptr_type): Likewise. + (struct_type): Likewise. + (union_type): Likewise. + (array_type): Likewise. + (named_type): Likewise. + (type_field_offset): Likewise. + (var_expression): Likewise. + (float_constant_expression): Likewise. + (string_constant_expression): Likewise. + (char_constant_expression): Likewise. + (wchar_constant_expression): Likewise. + (boolean_constant_expression): Likewise. + (convert_expression): Likewise. + (struct_field_expression): Likewise. + (compound_expression): Likewise. + (conditional_expression): Likewise. + (negation_expression): Likewise. + (arithmetic_or_logical_expression): Likewise. + (arithmetic_or_logical_expression_checked): Likewise. + (comparison_expression): Likewise. + (lazy_boolean_expression): Likewise. + (constructor_expression): Likewise. + (array_constructor_expression): Likewise. + (array_initializer): Likewise. + (array_index_expression): Likewise. + (call_expression): Likewise. + (init_statement): Likewise. + (assignment_statement): Likewise. + (return_statement): Likewise. + (if_statement): Likewise. + (loop_expression): Likewise. + (exit_expression): Likewise. + (statement_list): Likewise. + (exception_handler_statement): Likewise. + (block): Likewise. + (block_add_statements): Likewise. + (global_variable): Likewise. + (global_variable_set_init): Likewise. + (local_variable): Likewise. + (parameter_variable): Likewise. + (static_chain_variable): Likewise. + (temporary_variable): Likewise. + (label): Likewise. + (function): Likewise. + (function_defer_statement): Likewise. + (function_set_parameters): Likewise. + (write_global_definitions): Likewise. + (fill_in_fields): Likewise. + * rust-diagnostics.cc (expand_format): Likewise. + (expand_message): Likewise. + (va_constructor): Likewise. + * rust-diagnostics.h (RUST_ATTRIBUTE_GCC_DIAG): Likewise. + (rust_open_quote): Likewise. + (rust_close_quote): Likewise. + (rust_debug_loc): Likewise. + * rust-gcc.cc (non_zero_size_type): Likewise. + * rust-object-export.h (rust_field_alignment): Likewise. + (rust_read_export_data): Likewise. + (rust_write_export_data): Likewise. + * rust-session-manager.cc (saw_errors): Likewise. + (rust_get_linemap): Likewise. + (validate_crate_name): Likewise. + (Session::load_extern_crate): Likewise. + * rust-session-manager.h (rust_crate_name_validation_test): Likewise. + * rust-system.h (rust_preserve_from_gc): Likewise. + (rust_localize_identifier): Likewise. + * rust-target.h (rust_add_target_info): Likewise. + * typecheck/rust-autoderef.cc: + * typecheck/rust-casts.cc (TypeCastRules::cast_rules): Likewise. + * typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion): Likewise. + (TypeCoercionRules::coerce_unsafe_ptr): Likewise. + (TypeCoercionRules::coerce_borrowed_pointer): Likewise. + * typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): Likewise. + (TraitItemReference::is_object_safe): Likewise. + * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::resolve_literal): Likewise. + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. + (typecheck_inline_asm_operand): Likewise. + * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItem::visit): Likewise. + (TypeCheckImplItemWithTrait::visit): Likewise. + * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): Likewise. + * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::visit): Likewise. + * typecheck/rust-hir-type-check-type.cc + (TypeResolveGenericParam::apply_trait_bounds): Likewise. + (ResolveWhereClauseItem::visit): Likewise. + * typecheck/rust-hir-type-check.cc (saw_errors): Likewise. + (TraitItemReference::get_type_from_fn): Likewise. + * typecheck/rust-type-util.h (query_type): Likewise. + (types_compatable): Likewise. + (unify_site): Likewise. + (unify_site_and): Likewise. + (coercion_site): Likewise. + (try_coercion): Likewise. + (cast_site): Likewise. + * typecheck/rust-tyty-bounds.cc: + * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Likewise. + * typecheck/rust-tyty-cmp.h: + * typecheck/rust-tyty-variance-analysis.h (query_field_regions): Likewise. + * typecheck/rust-tyty.cc (BaseType::is_unit): Likewise. + (BaseType::has_substitutions_defined): Likewise. + (BaseType::needs_generic_substitutions): Likewise. + (BaseType::get_subst_argument_mappings): Likewise. + (InferType::default_type): Likewise. + (InferType::apply_primitive_type_hint): Likewise. + * typecheck/rust-tyty.h (is_primitive_type_kind): Likewise. + * typecheck/rust-unify.cc (UnifyRules::expect_inference_variable): Likewise. + (UnifyRules::expect_adt): Likewise. + (UnifyRules::expect_str): Likewise. + (UnifyRules::expect_reference): Likewise. + (UnifyRules::expect_pointer): Likewise. + (UnifyRules::expect_param): Likewise. + (UnifyRules::expect_array): Likewise. + (UnifyRules::expect_slice): Likewise. + (UnifyRules::expect_fndef): Likewise. + (UnifyRules::expect_fnptr): Likewise. + (UnifyRules::expect_tuple): Likewise. + (UnifyRules::expect_bool): Likewise. + (UnifyRules::expect_char): Likewise. + (UnifyRules::expect_int): Likewise. + (UnifyRules::expect_uint): Likewise. + (UnifyRules::expect_float): Likewise. + (UnifyRules::expect_isize): Likewise. + (UnifyRules::expect_usize): Likewise. + (UnifyRules::expect_never): Likewise. + (UnifyRules::expect_placeholder): Likewise. + (UnifyRules::expect_projection): Likewise. + (UnifyRules::expect_dyn): Likewise. + (UnifyRules::expect_closure): Likewise. + (UnifyRules::expect_opaque): Likewise. + * util/rust-abi.h (get_abi_from_string): Likewise. + (get_string_from_abi): Likewise. + * util/rust-attributes.cc (check_doc_attribute): Likewise. + * util/rust-base62.h (base62_integer): Likewise. + * util/rust-dir-owner.h (get_file_subdir): Likewise. + * util/rust-edition.h (get_rust_edition): Likewise. + * util/rust-punycode.h (encode_punycode): Likewise. + (rust_punycode_encode_test): Likewise. + * util/rust-token-converter.cc (convert): Likewise. + (from_tokenstream): Likewise. + * util/rust-token-converter.h (convert): Likewise. + (convert_literal): Likewise. + * util/rust-unicode.h (is_alphabetic): Likewise. + (is_ascii_only): Likewise. + (is_numeric): Likewise. + (is_nfc_qc_no): Likewise. + (is_nfc_qc_maybe): Likewise. + (nfc_quick_check): Likewise. + (rust_nfc_qc_test): Likewise. + (rust_utf8_normalize_test): Likewise. + (rust_utf8_property_test): Likewise. + * util/rust-unwrap-segment.h (unwrap_segment_node_id): Likewise. + +2025-08-05 Marc Poulhiès <dkm@kataplop.net> + + * Make-lang.in (GRS_OBJS): Remove rust-macro.o. + * ast/rust-macro.cc: Removed. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * parse/rust-parse-impl.h + (Parser::parse_attr_input): Handle more delimeter tokens and the + END_OF_FILE token. + (Parser::skip_after_end_attribute): Handle the END_OF_FILE + token. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * hir/rust-ast-lower-item.cc + (ASTLoweringItem::visit): Keep going after a duplicate field is + found. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * checks/errors/borrowck/rust-bir-builder-internal.h: Include + "rust-immutable-name-resolution-context.h" and "options.h". + (AbstractBuilder::resolve_label): Use the 2.0 name resolver when + it's enabled. + (AbstractBuilder::resolve_variable): Likewise. + (AbstractBuilder::resolve_variable_or_fn): Likewise. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * expand/rust-derive-default.cc (DeriveDefault::visit_struct): use builder + (DeriveDefault::visit_tuple): likewise + * expand/rust-derive-eq.cc (DeriveEq::visit_tuple): likewise + (DeriveEq::visit_struct): likewise + (DeriveEq::visit_enum): likewise + (DeriveEq::visit_union): likewise + +2025-08-05 Marc Poulhiès <dkm@kataplop.net> + + PR rust/120018 + * rust-attribs.cc (handle_noreturn_attribute): Reindent declaration. + (handle_leaf_attribute): Likewise. + (handle_const_attribute): Likewise. + (handle_malloc_attribute): Likewise. + (handle_pure_attribute): Likewise. + (handle_novops_attribute): Likewise. + (handle_nonnull_attribute): Likewise. + (handle_nothrow_attribute): Likewise. + (handle_type_generic_attribute): Likewise. + (handle_transaction_pure_attribute): Likewise. + (handle_returns_twice_attribute): Likewise. + (handle_fnspec_attribute): Likewise. + (handle_omp_declare_simd_attribute): Likewise. + (handle_cold_attribute): New. + (handle_hot_attribute): New. + (attribute_spec::exclusions attr_cold_hot_exclusions): New. + (grs_langhook_common_attributes): Make it static. + (grs_langhook_common_attribute_table): New. + (grs_langhook_gnu_attributes): New. + (grs_langhook_gnu_attribute_table): New. + (handle_malloc_attribute): Make it static. + (handle_fnspec_attribute): Likewise. + (handle_pure_attribute): Replace gcc_assert by explicit warning. + (handle_novops_attribute): Likewise. + (handle_nothrow_attribute): Likewise. + (handle_returns_twice_attribute): Likewise. + (handle_omp_declare_simd_attribute): Likewise and make it static. + * rust-lang.cc (grs_langhook_gnu_attribute_table): New. + (grs_langhook_common_attribute_table): Adjust type to new hook. + (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE): Remove. + (LANG_HOOKS_ATTRIBUTE_TABLE): New. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-path.cc + (TypePath::make_debug_string): Add definition. + * ast/rust-path.h + (TypePath::make_debug_string): Add declaration. + * resolve/rust-default-resolver.cc + (DefaultResolver::visit): Adjust InherentImpl and TraitImpl + visitors to better handle associated item scope. + * resolve/rust-default-resolver.h + (DefaultResolver::maybe_insert_big_self): Add. + * resolve/rust-late-name-resolver-2.0.cc + (Late::visit): Adjust type path resolution errors. + * resolve/rust-rib.h + (Rib::Kind): Add Generics kind. + * resolve/rust-toplevel-name-resolver-2.0.cc + (TopLevel::visit): Remove InherentImpl and TraitImpl visitor + overrides. + (TopLevel::maybe_insert_big_self): Add override in order to add + a definition of 'Self'. + * resolve/rust-toplevel-name-resolver-2.0.h + (TopLevel::visit): Remove InherentImpl and TraitImpl visitor + overrides. + (TopLevel::maybe_insert_big_self): Add override. + +2025-08-05 0xn4utilus <gyanendrabanjare8@gmail.com> + + * ast/rust-ast-collector.cc (TokenCollector::visit): Implement for InlineAsm. + * ast/rust-ast-full-decls.h (enum class): Move InlineAsmOption enum inside InlineAsm. + * ast/rust-expr.h (enum class): Likewise. + (class InlineAsm): Likewise. + * expand/rust-macro-builtins-asm.cc (check_and_set): Likewise. + (parse_options): Likewise. + * expand/rust-macro-builtins-asm.h (check_and_set): Likewise. + * hir/tree/rust-hir-expr.cc (InlineAsm::InlineAsm): Likewise. + * hir/tree/rust-hir-expr.h: Likewise. + * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. + +2025-08-05 Tom Schollenberger <tss2344@g.rit.edu> + + * backend/rust-constexpr.cc (eval_constant_expression): Check if t is a NULL_TREE + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * ast/rust-desugar-apit.cc: track if this is a impl-trait generic + * ast/rust-item.h (class TypeParam): add field to track if from impl trait + * hir/rust-ast-lower-type.cc (ASTLowerGenericParam::visit): likewise + * hir/tree/rust-hir-item.cc (TypeParam::TypeParam): upate hir as well + (TypeParam::operator=): likewise + * hir/tree/rust-hir-item.h (class TypeParam): likewise + * typecheck/rust-tyty-subst.cc (SubstitutionParamMapping::get_generic_param): add error + * typecheck/rust-tyty-subst.h: add const getter for the associated TypeParm + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * ast/rust-ast-visitor.cc + (DefaultASTVisitor::visit): Make call to EnumItem visitor from + EnumItem derived class visitors non-virtual. + * ast/rust-collect-lang-items.cc + (CollectLangItems::visit): Handle visitation of classes derived + from EnumItem. + * ast/rust-collect-lang-items.h + (CollectLangItems::visit): Likewise. + * resolve/rust-toplevel-name-resolver-2.0.cc + (TopLevel::visit): Call DefaultResolver::visit on EnumItem + instances. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * backend/rust-compile-pattern.cc + (CompilePatternCheckExpr::visit): Fix GENERIC generation in + light of enum layout changes since this code was written. + (CompilePatternBindings::handle_struct_pattern_ident_pat): + Delegate handling of child patterns to another + CompilePatternBindings::Compile call. + (CompilePatternBindings::make_struct_access): Make field name + parameter const qualified. + * backend/rust-compile-pattern.h + (CompilePatternBindings::make_struct_access): Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * resolve/rust-ast-resolve-item.cc + (ResolveItem::visit): Use the return values of + CanonicalPath::inherent_impl_seg and + CanonicalPath::trait_impl_projection_seg more directly. + * util/rust-canonical-path.h + (CanonicalPath::trait_impl_projection_seg): Append "<impl " + instead of "<" to the beginning of the returned path segment. + (CanonicalPath::inherent_impl_seg): Likewise. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * Make-lang.in: new desugar file + * ast/rust-ast.cc (ImplTraitTypeOneBound::as_string): its a unique_ptr now + (FormatArgs::set_outer_attrs): reformat + * ast/rust-path.h: remove has_generic_args assertion (can be empty because of desugar) + * ast/rust-type.h (class ImplTraitTypeOneBound): add copy ctor and use unique_ptr + * hir/rust-ast-lower-type.cc (ASTLoweringType::visit): update to use unique_ptr + * parse/rust-parse-impl.h (Parser::parse_type): reuse the existing unique_ptr instead + (Parser::parse_type_no_bounds): likewise + (Parser::parse_pattern): likewise + * resolve/rust-ast-resolve-type.cc (ResolveType::visit): its a unique_ptr now + * rust-session-manager.cc (Session::compile_crate): call desugar + * ast/rust-desugar-apit.cc: New file. + * ast/rust-desugar-apit.h: New file. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): allow impl type + * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): likewise + * hir/rust-ast-lower-type.cc (ASTLoweringType::ASTLoweringType): new flag for impl trait + (ASTLoweringType::translate): pass flag + (ASTLoweringType::visit): track impl trait tag + (ASTLoweringType::emit_impl_trait_error): new diagnostic + * hir/rust-ast-lower-type.h: add new field + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * expand/rust-derive-partial-eq.cc (DerivePartialEq::match_enum_tuple): Remove debug call. + (DerivePartialEq::match_enum_struct): Add proper implementation. + (DerivePartialEq::visit_enum): Call it. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * ast/rust-ast-builder.cc (Builder::struct_pattern_ident_pattern): New. + * ast/rust-ast-builder.h: New declaration. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * backend/rust-compile-pattern.cc (CompilePatternBindings::make_struct_access): + New function. + (CompilePatternBindings::visit): Properly implement patterns mentioned above + and call make_struct_accesss. + * backend/rust-compile-pattern.h: New declaration. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * backend/rust-compile-pattern.h: Split struct pattern compilation into three functions. + * backend/rust-compile-pattern.cc: Implement them. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * resolve/rust-late-name-resolver-2.0.cc (Late::Late): False initialize the + funny_error field. + 2025-07-25 David Malcolm <dmalcolm@redhat.com> * resolve/rust-ice-finalizer.cc: Update usage of "diagnostic_info" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f9f3de6..df2c843 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,667 @@ +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 + * g++.dg/cpp26/constexpr-new5.C: New test. + +2025-08-05 Mikael Morin <morin-mikael@orange.fr> + + * gfortran.dg/pointer_assign_16.f90: New test. + +2025-08-05 H.J. Lu <hjl.tools@gmail.com> + + PR target/121410 + * gcc.target/i386/pr121410.c: New test. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/execute/torture/offset_of1.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/execute/torture/const-generics-1.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/generics8.rs: extra error message + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3546.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3885.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/const_generics_3.rs: this works now + * rust/compile/const_generics_5.rs: likewise + * rust/compile/const_generics_8.rs: move the failure to another test case + * rust/compile/const_generics_10.rs: New test. + * rust/compile/const_generics_11.rs: New test. + * rust/compile/const_generics_12.rs: New test. + * rust/compile/const_generics_13.rs: New test. + * rust/compile/const_generics_14.rs: New test. + * rust/compile/const_generics_15.rs: New test. + * rust/compile/const_generics_16.rs: New test. + * rust/compile/const_generics_9.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3960.rs: New test. + +2025-08-05 Ryutaro Okada <1015ryu88@gmail.com> + + * rust/compile/auto_traits2.rs: + emove warning for unused `self` parameter + * rust/compile/derive-debug1.rs: + emove warning for unused `self` parameter + * rust/compile/derive_macro1.rs: + Remove warning for unused `self` parameter + * rust/compile/format_args_basic_expansion.rs: + Remove warning for unused `self` parameter + * rust/compile/format_args_extra_comma.rs: + Remove warning for unused `self` parameter + * rust/compile/issue-2043.rs: + Remove warning for unused `self` parameter + * rust/compile/issue-2166.rs: + Remove warning for unused `self` parameter + * rust/compile/issue-2238.rs: + Remove warning for unused `self` parameter + * rust/compile/issue-2907.rs: + Remove warning for unused `self` parameter + * rust/compile/min_specialization1.rs: + Remove warning for unused `self` parameter + * rust/compile/name_resolution2.rs: + Remove warning for unused `self` parameter + * rust/compile/name_resolution4.rs: + Remove warning for unused `self` parameter + * rust/compile/torture/generics29.rs: + Remove warning for unused `self` parameter + * rust/compile/torture/generics30.rs: + Remove warning for unused `self` parameter + * rust/compile/torture/traits3.rs: + Remove warning for unused `self` parameter + * rust/compile/torture/traits7.rs: + Remove warning for unused `self` parameter + * rust/execute/torture/impl_trait3.rs: + Remove warning for unused `self` parameter + * rust/execute/torture/min_specialization2.rs: + Remove warning for unused `self` parameter + * rust/execute/torture/trait10.rs: + Remove warning for unused `self` parameter + * rust/execute/torture/trait11.rs: + Remove warning for unused `self` parameter + * rust/execute/torture/trait12.rs: + Remove warning for unused `self` parameter + * rust/execute/torture/trait13.rs: + Remove warning for unused `self` parameter + * rust/execute/torture/trait9.rs: + Remove warning for unused `self` parameter + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/compile/while_let1.rs: New test. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/compile/offset_of2.rs: New test. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/compile/offset_of1.rs: New test. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * rust/compile/issue-4006.rs: New test. + +2025-08-05 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * rust/execute/inline_asm_inout_ident.rs: New test. + * rust/execute/inline_asm_inout_var.rs: New test. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * rust/compile/match-slicepattern-slice.rs: New file. + * rust/execute/torture/match-slicepattern-slice-1.rs: New file. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/compile/try_block1.rs: New test. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/compile/deferred_const_inference.rs: New test. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/compile/glob_import_enum.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3915.rs: New test. + * rust/execute/torture/sip-hasher.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3916.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3978.rs: New test. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/parse_simple_path_fail_1.rs: New test. + * rust/compile/parse_simple_path_fail_2.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3524.rs: New test. + +2025-08-05 lishin <lishin1008@gmail.com> + + * rust/compile/loop_constant_context.rs: New test. + * rust/compile/issue-3618.rs: + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * rust/compile/match-slicepattern-array.rs: New file. + * rust/execute/torture/match-slicepattern-array-1.rs: New file. + +2025-08-05 Yap Zhi Heng <yapzhhg@gmail.com> + + * rust/compile/slicepattern-size-mismatch.rs: New file. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/execute/torture/issue-2005.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-1048.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3144.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3599.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3876.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-2680.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/derive_partial_ord1.rs: this is now fully supported + * rust/execute/torture/basic_partial_ord1.rs: add missing i32 impl + * rust/execute/torture/basic_partial_ord2.rs: likewise + * rust/compile/issue-3836.rs: New test. + * rust/execute/torture/issue-3836.rs: New test. + * rust/execute/torture/partial-ord-6.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3874.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/all-cast.rs: shows array capacity now + * rust/compile/arrays2.rs: likewise + * rust/compile/const3.rs: fix error message + * rust/compile/const_generics_3.rs: disable until typecheck we get proper errors now! + * rust/compile/usize1.rs: proper capacity error message + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/compile/while_let_without_label.rs: New test. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/additional-trait-bounds2nr2.rs: Remove + -frust-name-resolution-2.0 usage. + * rust/compile/const_generics_3.rs: Likewise. + * rust/compile/enum_variant_name.rs: Likewise. + * rust/compile/generics9.rs: Likewise. + * rust/compile/invalid_label_name.rs: Likewise. + * rust/compile/issue-3304.rs: Likewise. + * rust/compile/macros/mbe/macro-issue3708.rs: Likewise. + * rust/compile/macros/mbe/macro-issue3709-2.rs: Likewise. + * rust/compile/name_resolution10.rs: Likewise. + * rust/compile/name_resolution11.rs: Likewise. + * rust/compile/name_resolution12.rs: Likewise. + * rust/compile/name_resolution13.rs: Likewise. + * rust/compile/name_resolution14.rs: Likewise. + * rust/compile/name_resolution15.rs: Likewise. + * rust/compile/name_resolution16.rs: Likewise. + * rust/compile/name_resolution17.rs: Likewise. + * rust/compile/name_resolution18.rs: Likewise. + * rust/compile/name_resolution20.rs: Likewise. + * rust/compile/name_resolution22.rs: Likewise. + * rust/compile/name_resolution23.rs: Likewise. + * rust/compile/name_resolution24.rs: Likewise. + * rust/compile/name_resolution25.rs: Likewise. + * rust/compile/name_resolution6.rs: Likewise. + * rust/compile/name_resolution7.rs: Likewise. + * rust/compile/name_resolution8.rs: Likewise. + * rust/compile/name_resolution9.rs: Likewise. + * rust/compile/nested_macro_definition.rs: Likewise. + * rust/compile/pub_restricted_1.rs: Likewise. + * rust/compile/pub_restricted_2.rs: Likewise. + * rust/compile/self-in-impl.rs: Likewise. + * rust/compile/self_import_namespace.rs: Likewise. + * rust/compile/use_1.rs: Likewise. + * rust/compile/xfail/name_resolution21.rs: Likewise. + * rust/execute/torture/name_resolution.rs: Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/compile.exp: Removed. + * rust/compile/nr2/exclude: Removed. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * rust/compile/match-restpattern-tuple-1.rs: New file. + * rust/compile/match-restpattern-tuple-2.rs: New file. + * rust/execute/torture/match-restpattern-tuple.rs: New file. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * rust/compile/tuple_mismatch.rs: Include RestPattern in test. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove issue-3315-2.rs. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove torture/alt_patterns1.rs. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/macros/builtin/recurse2.rs: Match "abheyho\0" as + well as "abheyho", to handle slight differences in assembly + output for null-terminated strings. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3525.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-3551.rs: New test. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * rust/compile/match-tuplestructpattern.rs: New file. + * rust/execute/torture/match-tuplestructpattern.rs: New file. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove issue-3642.rs. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/silly-order-bug.rs: New test. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove entries. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/execute/torture/issue-1481.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/nr2/exclude: nr2 puts out an extra error + * rust/compile/issue-3642.rs: New test. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/execute/black_box.rs: Return 0 from main. + * rust/execute/match-identifierpattern-enum.rs: Move to... + * rust/execute/xfail/match-identifierpattern-enum.rs: ...here. + * rust/execute/execute.exp: New file. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/bug-with-default-generic.rs: New test. + * rust/execute/torture/partial-eq-1.rs: New test. + * rust/execute/torture/partial-eq-2.rs: New test. + * rust/execute/torture/partial-eq-3.rs: New test. + * rust/execute/torture/partial-eq-4.rs: New test. + * rust/execute/torture/partial-ord-1.rs: New test. + * rust/execute/torture/partial-ord-2.rs: New test. + * rust/execute/torture/partial-ord-3.rs: New test. + * rust/execute/torture/partial-ord-4.rs: New test. + * rust/execute/torture/partial-ord-5.rs: New test. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * rust/compile/match-identifierpattern-enum.rs: New file. + * rust/execute/match-identifierpattern-enum.rs: New file. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove entries. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/compile/derive_partial_ord1.rs: New test. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/execute/torture/derive-partialeq2.rs: Add declaration for + discriminant_value. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/execute/torture/basic_partial_ord1.rs: New test. + * rust/execute/torture/basic_partial_ord2.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/const_generics_3.rs: + * rust/compile/issue-3660.rs: New test. + +2025-08-05 Zhi Heng <yapzhhg@gmail.com> + + * rust/compile/match-identifierpattern.rs: New file. + * rust/execute/torture/match-identifierpattern.rs: New file. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove entries. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove entries. + * rust/compile/pub_restricted_1.rs: Adjust expected error + messages and only run with name resolution 2.0 enabled. + * rust/compile/pub_restricted_2.rs: Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove canonical_paths1.rs. + +2025-08-05 Vishruth-Thimmaiah <vishruththimmaiah@gmail.com> + + * rust/compile/torture/unended-raw-byte-string.rs: + New test to ensure correct error message for unended raw byte string. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/issue-3671.rs: Remove usage of Self. + * rust/compile/nr2/exclude: Remove issue-3671.rs. + * rust/compile/self-in-impl.rs: New test. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove entries. + +2025-08-05 Vishruth-Thimmaiah <vishruththimmaiah@gmail.com> + + * rust/compile/torture/extern_mod2.rs: + New test to ensure an error is emitted for empty path attributes. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/execute/torture/const_block1.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/traits9.rs: update errors + * rust/compile/unify-errors1.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/bad-rpit1.rs: New test. + * rust/execute/torture/impl_rpit1.rs: New test. + * rust/execute/torture/impl_rpit2.rs: New test. + * rust/execute/torture/impl_rpit3.rs: New test. + +2025-08-05 Parthib <parthibdutta02@gmail.com> + + * lib/rust.exp: Remove timeout. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/execute/torture/for-loop1.rs: Adjust paths. + * rust/execute/torture/for-loop2.rs: Likewise. + * rust/execute/torture/iter1.rs: Likewise. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/execute/torture/builtin_abort.rs: Fix path to + intrinsics::abort. + +2025-08-05 Tom Schollenberger <tss2344@g.rit.edu> + + * rust/compile/issue-3661.rs: Test NR2 has expected behavior + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/macros/mbe/meta-param.rs: New test. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/execute/same_field_name.rs: Move to... + * rust/compile/same_field_name.rs: ...here and adjust expected + errors. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/nr2/exclude: these are fixed now + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/compile/nr2/exclude: Remove entries. + +2025-08-05 Tom Schollenberger <tss2344@g.rit.edu> + + * rust/compile/issue-3618.rs: Test empty loops error properly. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/nr2/exclude: nr2 cant handle this + * rust/compile/impl_trait_generic_arg.rs: New test. + +2025-08-05 Owen Avery <powerboat9.gamer@gmail.com> + + * rust/execute/torture/struct-pattern-match.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/issue-2015.rs: fully supported now + * rust/compile/nr2/exclude: nr2 cant handle some of these + * rust/compile/issue-1487.rs: New test. + * rust/compile/issue-3454.rs: New test. + * rust/execute/torture/impl_desugar-2.rs: New test. + * rust/execute/torture/impl_desugar.rs: New test. + * rust/execute/torture/impl_trait1.rs: New test. + * rust/execute/torture/impl_trait2.rs: New test. + * rust/execute/torture/impl_trait3.rs: New test. + * rust/execute/torture/impl_trait4.rs: New test. + * rust/execute/torture/issue-1482.rs: New test. + +2025-08-05 Philip Herron <herron.philip@googlemail.com> + + * rust/compile/impl_trait_diag.rs: New test. + * rust/compile/issue-1485.rs: New test. + +2025-08-05 CohenArthur <cohenarthur.dev@gmail.com> + Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * rust/execute/torture/derive-partialeq2.rs: Add missing terminating nul char. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/execute/torture/derive-partialeq2.rs: New test. + +2025-08-05 Arthur Cohen <arthur.cohen@embecosm.com> + + * rust/execute/torture/struct_pattern1.rs: New test. + +2025-08-05 Georg-Johann Lay <avr@gjlay.de> + + PR target/121359 + * gcc.target/avr/torture/pr118591-1.c: Remove -mlra. + * gcc.target/avr/torture/pr118591-2.c: Same. + +2025-08-05 Richard Biener <rguenther@suse.de> + + PR tree-optimization/121395 + * gcc.dg/vect/pr59984.c: Adjust. + +2025-08-05 Richard Biener <rguenther@suse.de> + + PR tree-optimization/121382 + * gcc.dg/torture/pr121382.c: New testcase. + +2025-08-05 Richard Biener <rguenther@suse.de> + + PR tree-optimization/121370 + * gcc.dg/torture/pr121370.c: New testcase. + +2025-08-05 Yang Yujie <yangyujie@loongson.cn> + + * gcc.dg/bitintext.h (S, CEIL, PROMOTED_SIZE): Define. + (BEXTC): Generalize to only check extension within PROMOTED_SIZE bits. + +2025-08-05 Jakub Jelinek <jakub@redhat.com> + + PR preprocessor/120778 + * g++.dg/DRs/dr2579.C: New test. + * c-c++-common/cpp/va-opt-6.c: Expect ' rather than \" around + tokens in incorrect pasting diagnostics. + * gcc.dg/c23-attr-syntax-6.c: Likewise. + * gcc.dg/cpp/paste12.c: Likewise. + * gcc.dg/cpp/paste12-2.c: Likewise. + * gcc.dg/cpp/paste14.c: Likewise. + * gcc.dg/cpp/paste14-2.c: Likewise. + +2025-08-05 Pan Li <pan2.li@intel.com> + + * gcc.target/riscv/sat/sat_u_mul-1-u32-from-u64.c: Add mulhu + asm check. + * gcc.target/riscv/sat/sat_u_mul-1-u64-from-u128.c: Ditto. + 2025-08-04 Patrick Palka <ppalka@redhat.com> PR c++/121351 diff --git a/gcc/testsuite/c-c++-common/cpp/comment-ff-1.c b/gcc/testsuite/c-c++-common/cpp/comment-ff-1.c new file mode 100644 index 0000000..0d071b1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/comment-ff-1.c @@ -0,0 +1,12 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// Test that form-feed followed by non-whitespace +// in line comments are accepted. +// { dg-do compile } +// { dg-options "-pedantic-errors -Wall -W" } + +// +int a; +// +int b; +// comment +int c; diff --git a/gcc/testsuite/c-c++-common/cpp/comment-vtab-1.c b/gcc/testsuite/c-c++-common/cpp/comment-vtab-1.c new file mode 100644 index 0000000..03feb73 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cpp/comment-vtab-1.c @@ -0,0 +1,12 @@ +// C++26 P2843R3 - Preprocessing is never undefined +// Test that vertical tab followed by non-whitespace +// in line comments are accepted. +// { dg-do compile } +// { dg-options "-pedantic-errors -Wall -W" } + +// +int a; +// +int b; +// comment +int c; diff --git a/gcc/testsuite/c-c++-common/gomp/map-6.c b/gcc/testsuite/c-c++-common/gomp/map-6.c index 852839e..d76f9ae 100644 --- a/gcc/testsuite/c-c++-common/gomp/map-6.c +++ b/gcc/testsuite/c-c++-common/gomp/map-6.c @@ -13,20 +13,20 @@ foo (void) #pragma omp target map (to:a) ; - #pragma omp target map (a to: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present'" "" { target c++ } } */ - ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ + #pragma omp target map (a to: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present'" "" { target c++ } } */ + ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ - #pragma omp target map (close, a to: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present'" "" { target c++ } } */ - ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ + #pragma omp target map (close, a to: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present'" "" { target c++ } } */ + ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ - #pragma omp target enter data map(b7) map (close, a to: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present'" "" { target c++ } } */ - ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ + #pragma omp target enter data map(b7) map (close, a to: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present'" "" { target c++ } } */ + ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ - #pragma omp target exit data map(b7) map (close, a from: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present'" "" { target c++ } } */ - ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ + #pragma omp target exit data map(b7) map (close, a from: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present'" "" { target c++ } } */ + ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ - #pragma omp target data map(b7) map (close, a from: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present'" "" { target c++ } } */ - ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ + #pragma omp target data map(b7) map (close, a from: b) /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present'" "" { target c++ } } */ + ; /* { dg-error "'map' clause with map-type modifier other than 'always', 'close', 'iterator', 'mapper' or 'present' before 'a'" "" { target c } .-1 } */ #pragma omp target map (close a) /* { dg-error "'close' undeclared" "" { target c } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/target-map-iterators-1.c b/gcc/testsuite/c-c++-common/gomp/target-map-iterators-1.c new file mode 100644 index 0000000..7d6c8dc --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-map-iterators-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +#define DIM1 17 +#define DIM2 39 + +void f (int **x, int **y) +{ + #pragma omp target map(iterator(i=0:DIM1), to: x[i][:DIM2]) + ; + + #pragma omp target map(iterator(i=0:DIM1), to: x[i][:DIM2], y[i][:DIM2]) + ; + + #pragma omp target map(iterator(i=0:DIM1), to: x[i][:DIM2] + 2) /* { dg-message "unsupported map expression" } */ + ; + + #pragma omp target map(iterator(i=0:DIM1), iterator(j=0:DIM2), to: x[i][j]) /* { dg-error "too many 'iterator' modifiers" } */ + ; + + #pragma omp target map(iterator(i=0:DIM1), to: (i % 2 == 0) ? x[i] : y[i]) /* { dg-message "unsupported map expression" } */ + ; +} diff --git a/gcc/testsuite/c-c++-common/gomp/target-map-iterators-2.c b/gcc/testsuite/c-c++-common/gomp/target-map-iterators-2.c new file mode 100644 index 0000000..42c6d75 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-map-iterators-2.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +void f (int *x, float *y, double *z) +{ + #pragma omp target map(iterator(i=0:10), to: x) /* { dg-warning "iterator variable 'i' not used in clause expression" } */ + /* Add a reference to x to ensure that the 'to' clause does not get + dropped. */ + x[0] = 0; + + #pragma omp target map(iterator(i2=0:10, j2=0:20), from: x[i2]) /* { dg-warning "iterator variable 'j2' not used in clause expression" } */ + ; + + #pragma omp target map(iterator(i3=0:10, j3=0:20, k3=0:30), to: x[i3+j3], y[j3+k3], z[k3+i3]) + /* { dg-warning "iterator variable 'i3' not used in clause expression" "" { target *-*-* } .-1 } */ + /* { dg-warning "iterator variable 'j3' not used in clause expression" "" { target *-*-* } .-2 } */ + /* { dg-warning "iterator variable 'k3' not used in clause expression" "" { target *-*-* } .-3 } */ + ; + + /* Test iterator with zero iterations. */ + #pragma omp target map(iterator(i4=0:0), to: x[i4]) /* { dg-warning "iteration count is zero" } */ + ; + + /* Test iterator where the beginning is greater than the end. */ + #pragma omp target map(iterator(i5=10:0), to: x[i5]) /* { dg-warning "iteration count is zero" } */ + ; + + /* Test iterator where the beginning is greater than the end, but with a + negative step. */ + #pragma omp target map(iterator(i6=10:0:-1), to: x[i6]) + ; +} + +/* { dg-final { scan-tree-dump-times "map\\\(to:x" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\\(iterator\\\(int i2=0:10:1, loop_label=\[^\\\)\]+\\\):from:" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\\(iterator\\\(int i3=0:10:1, int j3=0:20:1, loop_label=\[^\\\)\]+\\\):to:" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\\(iterator\\\(int j3=0:20:1, int k3=0:30:1, loop_label=\[^\\\)\]+\\\):to:" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\\(iterator\\\(int i3=0:10:1, int k3=0:30:1, loop_label=\[^\\\)\]+\\\):to:" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\\(iterator\\\(int i4=0:0:1, loop_label=\[^\\\)\]+\\\):to:" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\\(iterator\\\(int i5=10:0:1, loop_label=\[^\\\)\]+\\\):to:" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\\(iterator\\\(int i6=10:0:-1, loop_label=\[^\\\)\]+\\\):to:" 1 "gimple" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/target-map-iterators-3.c b/gcc/testsuite/c-c++-common/gomp/target-map-iterators-3.c new file mode 100644 index 0000000..62df42f --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-map-iterators-3.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +#define DIM1 10 +#define DIM2 20 +#define DIM3 30 + +void f (int ***x, float ***y, double **z) +{ + #pragma omp target \ + map(to: x, y) \ + map(iterator(i=0:DIM1, j=0:DIM2), to: x[i][j][:DIM3], y[i][j][:DIM3]) \ + map(from: z) \ + map(iterator(i=0:DIM1), from: z[i][:DIM2]) + ; +} + +/* { dg-final { scan-tree-dump-times "if \\(i <= 9\\) goto <D\\\.\[0-9\]+>; else goto <D\\\.\[0-9\]+>;" 3 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "if \\(j <= 19\\) goto <D\\\.\[0-9\]+>; else goto <D\\\.\[0-9\]+>;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\(iterator\\(int i=0:10:1, loop_label=<D\\\.\[0-9\]+>, elems=omp_iter_data\\\.\[0-9\]+, index=D\\\.\[0-9\]+\\):from:\\*D\\\.\[0-9\]+" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\(iterator\\(int i=0:10:1, loop_label=<D\\\.\[0-9\]+>, elems=omp_iter_data\\\.\[0-9\]+, index=D\\\.\[0-9\]+\\):attach:\\*D\\\.\[0-9\]+" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\(iterator\\(int i=0:10:1, int j=0:20:1, loop_label=<D\\\.\[0-9\]+>, elems=omp_iter_data\\\.\[0-9\]+, index=D\\\.\[0-9\]+\\):to:\\*D\\\.\[0-9\]+" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\(iterator\\(int i=0:10:1, int j=0:20:1, loop_label=<D\\\.\[0-9\]+>, elems=omp_iter_data\\\.\[0-9\]+, index=D\\\.\[0-9\]+\\):attach:\\*D\\\.\[0-9\]+" 4 "gimple" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/target-map-iterators-4.c b/gcc/testsuite/c-c++-common/gomp/target-map-iterators-4.c new file mode 100644 index 0000000..5dc5ad5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-map-iterators-4.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ +/* { dg-additional-options "-std=c++98" { target c++ } } */ + +int bar (int, int); +void baz (int, int *); +#pragma omp declare target enter (baz) + +void +foo (int x, int *p) +{ + #pragma omp target map (iterator (i=0:4), to: p[bar (x, i)]) + baz (x, p); +} + +/* { dg-final { scan-tree-dump "firstprivate\\\(x\\\)" "gimple" } } */ +/* { dg-final { scan-tree-dump-times "bar \\\(x, i\\\)" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "map\\\(iterator\\\(int i=0:4:1, loop_label=" 2 "gimple" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/target-update-iterators-1.c b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-1.c new file mode 100644 index 0000000..53b22f0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp" } */ + +#define DIM1 17 +#define DIM2 39 + +void f (int **x, float **y) +{ + #pragma omp target update to (iterator(i=0:DIM1): x[i][:DIM2]) + + #pragma omp target update to (iterator(i=0:DIM1): x[i][:DIM2], y[i][:DIM2]) + + #pragma omp target update to (iterator(i=0:DIM1), present: x[i][:DIM2]) + + #pragma omp target update to (iterator(i=0:DIM1), iterator(j=0:DIM2): x[i][j]) /* { dg-error "too many 'iterator' modifiers" } */ + /* { dg-error "'#pragma omp target update' must contain at least one 'from' or 'to' clauses" "" { target *-*-* } .-1 } */ + + #pragma omp target update from (iterator(i=0:DIM1), something: x[i][j]) /* { dg-error "'from' clause with modifier other than 'iterator' or 'present'" } */ + /* { dg-error "expected '\\)' before 'something'" "" { target c } .-1 } */ + /* { dg-error "'#pragma omp target update' must contain at least one 'from' or 'to' clauses" "" { target *-*-* } .-2 } */ +} diff --git a/gcc/testsuite/c-c++-common/gomp/target-update-iterators-2.c b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-2.c new file mode 100644 index 0000000..dbd43e0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +void f (int *x, float *y, double *z) +{ + #pragma omp target update to(iterator(i=0:10): x) /* { dg-warning "iterator variable 'i' not used in clause expression" }*/ + ; + + #pragma omp target update from(iterator(i2=0:10, j2=0:20): x[i2]) /* { dg-warning "iterator variable 'j2' not used in clause expression" }*/ + ; + + #pragma omp target update to(iterator(i3=0:10, j3=0:20, k3=0:30): x[i3+j3], y[j3+k3], z[k3+i3]) + /* { dg-warning "iterator variable 'i3' not used in clause expression" "" { target *-*-* } .-1 } */ + /* { dg-warning "iterator variable 'j3' not used in clause expression" "" { target *-*-* } .-2 } */ + /* { dg-warning "iterator variable 'k3' not used in clause expression" "" { target *-*-* } .-3 } */ + ; +} + +/* { dg-final { scan-tree-dump "update to\\\(x " "gimple" } } */ +/* { dg-final { scan-tree-dump "update from\\\(iterator\\\(int i2=0:10:1, loop_label=" "gimple" } } */ +/* { dg-final { scan-tree-dump "to\\\(iterator\\\(int i3=0:10:1, int k3=0:30:1, loop_label=" "gimple" } } */ +/* { dg-final { scan-tree-dump "to\\\(iterator\\\(int j3=0:20:1, int k3=0:30:1, loop_label=" "gimple" } } */ +/* { dg-final { scan-tree-dump "to\\\(iterator\\\(int i3=0:10:1, int j3=0:20:1, loop_label=" "gimple" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/target-update-iterators-3.c b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-3.c new file mode 100644 index 0000000..ef55216 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/target-update-iterators-3.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-fopenmp -fdump-tree-gimple" } */ + +#define DIM1 10 +#define DIM2 20 +#define DIM3 30 + +void f (int ***x, float ***y, double **z) +{ + #pragma omp target update to (iterator(i=0:DIM1, j=0:DIM2): x[i][j][:DIM3], y[i][j][:DIM3]) + #pragma omp target update from (iterator(i=0:DIM1): z[i][:DIM2]) +} + +/* { dg-final { scan-tree-dump-times "if \\(i <= 9\\) goto <D\.\[0-9\]+>; else goto <D\.\[0-9\]+>;" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "if \\(j <= 19\\) goto <D\.\[0-9\]+>; else goto <D\.\[0-9\]+>;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "to\\(iterator\\(int i=0:10:1, int j=0:20:1, loop_label=<D\.\[0-9\]+>, elems=omp_iter_data\.\[0-9\]+, index=D\.\[0-9\]+\\):\\*D\.\[0-9\]+" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "from\\(iterator\\(int i=0:10:1, loop_label=<D\.\[0-9\]+>, elems=omp_iter_data\.\[0-9\]+, index=D\.\[0-9\]+\\):\\*D\.\[0-9\]+" 1 "gimple" } } */ diff --git a/gcc/testsuite/g++.dg/abi/mangle82.C b/gcc/testsuite/g++.dg/abi/mangle82.C new file mode 100644 index 0000000..39dd581 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle82.C @@ -0,0 +1,85 @@ +// Test mangling of C++20 class NTTP objects with implicitly zeroed +// non-trailing subojects. +// PR c++/121231 +// { dg-do compile { target c++20 } } + +struct A { + int x, y, z; + + static constexpr A make(int x, int y, int z) { + A a{}; + if (x != 0) + a.x = x; + if (y != 0) + a.y = y; + if (z != 0) + a.z = z; + return a; + } +}; + +struct B : A { + int w; + + static constexpr B make(int x, int y, int z, int w) { + B b{}; + if (x != 0 || y != 0 || z != 0) + static_cast<A&>(b) = A::make(x, y, z); + if (w != 0) + b.w = w; + return b; + } +}; + +struct C { + int xyz[3]; + + static constexpr C make(int x, int y, int z) { + C c{}; + if (x != 0) + c.xyz[0] = x; + if (y != 0) + c.xyz[1] = y; + if (z != 0) + c.xyz[2] = z; + return c; + } +}; + +template<int N, A a> void f(); +template<int N, B b> void g(); +template<int N, C c> void h(); + +int main() { + f<0, A::make(0, 0, 1)>(); // void f<0, A{0, 0, 1}>() + f<1, A::make(0, 1, 0)>(); // void f<1, A{0, 1}>() + f<2, A::make(0, 0, 0)>(); // void f<2, A{}>() + f<3, A::make(1, 0, 1)>(); // void f<3, A{1, 0, 1}>() + + g<0, B::make(0, 0, 0, 1)>(); // void g<0, B{A{}, 1}>() + g<1, B::make(0, 0, 1, 0)>(); // void g<1, B{A{0, 0, 1}}>() + g<2, B::make(0, 1, 0, 0)>(); // void g<2, B{A{0, 1}}>() + g<3, B::make(0, 0, 0, 0)>(); // void g<3, B{}>() + g<4, B::make(1, 0, 1, 0)>(); // void g<4, B{A{1, 0, 1}}>() + + h<0, C::make(0, 0, 1)>(); // void h<0, C{int [3]{0, 0, 1}}>() + h<1, C::make(0, 1, 0)>(); // void h<1, C{int [3]{0, 1}}>() + h<2, C::make(0, 0, 0)>(); // void h<2, C{}>() + h<3, C::make(1, 0, 1)>(); // void h<3, C{int [3]{1, 0, 1}}>() +} + +// { dg-final { scan-assembler "_Z1fILi0EXtl1ALi0ELi0ELi1EEEEvv" } } +// { dg-final { scan-assembler "_Z1fILi1EXtl1ALi0ELi1EEEEvv" } } +// { dg-final { scan-assembler "_Z1fILi2EXtl1AEEEvv" } } +// { dg-final { scan-assembler "_Z1fILi3EXtl1ALi1ELi0ELi1EEEEvv" } } + +// { dg-final { scan-assembler "_Z1gILi0EXtl1Btl1AELi1EEEEvv" } } +// { dg-final { scan-assembler "_Z1gILi1EXtl1Btl1ALi0ELi0ELi1EEEEEvv" } } +// { dg-final { scan-assembler "_Z1gILi2EXtl1Btl1ALi0ELi1EEEEEvv" } } +// { dg-final { scan-assembler "_Z1gILi3EXtl1BEEEvv" } } +// { dg-final { scan-assembler "_Z1gILi4EXtl1Btl1ALi1ELi0ELi1EEEEEvv" } } + +// { dg-final { scan-assembler "_Z1hILi0EXtl1CtlA3_iLi0ELi0ELi1EEEEEvv" } } +// { dg-final { scan-assembler "_Z1hILi1EXtl1CtlA3_iLi0ELi1EEEEEvv" } } +// { dg-final { scan-assembler "_Z1hILi2EXtl1CEEEvv" } } +// { dg-final { scan-assembler "_Z1hILi3EXtl1CtlA3_iLi1ELi0ELi1EEEEEvv" } } diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-new3.C b/gcc/testsuite/g++.dg/cpp26/constexpr-new3.C index 6a06a6e..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 'heap ' 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/constexpr-new5.C b/gcc/testsuite/g++.dg/cpp26/constexpr-new5.C new file mode 100644 index 0000000..b98b9e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp26/constexpr-new5.C @@ -0,0 +1,43 @@ +// PR c++/121068 +// { dg-do compile { target c++26 } } + +#include <new> + +struct S +{ + constexpr S() = default; + constexpr S(int x) : s(x) {} + constexpr S(S&& x) : s(x.s) {} + constexpr S& operator=(S&& x) { s = x.s; return *this; } + unsigned char s; +}; + +constexpr +int foo() +{ + union { S a[20]; }; + new (&a) S[20](); // OK + for (int i = 0; i < 20; ++i) + a[i].~S(); + + auto* sf = ::new(&a[2]) S(11); + return 1; +} + +static_assert(foo()); + +constexpr +int foo2() +{ + union { S a[20]; }; + new (&a) S[20]; // ILL-FORMED + for (int i = 0; i < 20; ++i) + a[i].~S(); + + auto* sf = ::new(&a[2]) S(11); + return 1; +} + +static_assert(foo2()); + +auto p = foo2; diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class73.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class73.C new file mode 100644 index 0000000..7f27cad --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class73.C @@ -0,0 +1,30 @@ +// PR c++/119688 +// { dg-do compile { target c++20 } } + +template<int N> +struct builder { + bool value[256]{}; + constexpr builder(char const (&s)[N]) { + for(int i = 0 ; i < N; ++i) + value[static_cast<unsigned char>(s[i])] = true; + } +}; + +template<builder A> +constexpr auto operator""_ar() { + return A.value; +} + +constexpr auto first = "ab"_ar; +static_assert( first['a']); +static_assert( first['b']); +static_assert(!first['c']); +static_assert(!first['d']); +static_assert(!first['z']); + +constexpr auto second = "cd"_ar; +static_assert(!second['a']); +static_assert(!second['b']); +static_assert(!second['z']); +static_assert( second['c']); +static_assert( second['d']); diff --git a/gcc/testsuite/gcc.dg/bitint-125.c b/gcc/testsuite/gcc.dg/bitint-125.c new file mode 100644 index 0000000..5ef0e32 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-125.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/121127 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2 -w" } */ + +#if __BITINT_MAXWIDTH__ >= 576 +_BitInt(575) +foo (void) +{ + _BitInt(576) d; + _BitInt(575) e = d * 42wb; + return e; +} +#else +int i; +#endif diff --git a/gcc/testsuite/gcc.dg/bitintext.h b/gcc/testsuite/gcc.dg/bitintext.h index d5f2689d..f61cf9a 100644 --- a/gcc/testsuite/gcc.dg/bitintext.h +++ b/gcc/testsuite/gcc.dg/bitintext.h @@ -25,22 +25,20 @@ do_copy (void *p, const void *q, __SIZE_TYPE__ r) /* Macro to test whether (on targets where psABI requires it) _BitInt with padding bits have those filled with sign or zero extension. */ #if defined(__s390x__) || defined(__arm__) || defined(__loongarch__) +#define BEXTC1(x, uns) \ + do { \ + uns _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \ + do_copy (&__x, &(x), sizeof (__x)); \ + if (__x != (typeof (x)) __x) \ + __builtin_abort (); \ + } while (0) + #define BEXTC(x) \ - do { \ - if ((typeof (x)) -1 < 0) \ - { \ - _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \ - do_copy (&__x, &(x), sizeof (__x)); \ - if (__x != (x)) \ - __builtin_abort (); \ - } \ - else \ - { \ - unsigned _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \ - do_copy (&__x, &(x), sizeof (__x)); \ - if (__x != (x)) \ - __builtin_abort (); \ - } \ + do { \ + if ((typeof (x)) -1 < 0) \ + BEXTC1 ((x), signed); \ + else \ + BEXTC1 ((x), unsigned); \ } while (0) #else #define BEXTC(x) do { (void) (x); } while (0) diff --git a/gcc/testsuite/gcc.dg/pr121217.c b/gcc/testsuite/gcc.dg/pr121217.c new file mode 100644 index 0000000..313f1e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr121217.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu17" } */ + +typedef union{ + char *nordic_ref; + unsigned long long int bit_number; + enum PinMode mode : 2; /* { dg-warning "narrower" } */ + /* { dg-error "field 'mode'" "" { target *-*-* } .-1 } */ + unsigned char value; + } s; typedef struct{ + union{ + char *nordic_ref; + unsigned long long int bit_number; + enum PinMode mode : 2; /* { dg-warning "narrower" } */ + /* { dg-error "field 'mode'" "" { target *-*-* } .-1 } */ + unsigned char value; + } s; +} /* { dg-error "expected identifier" } */ + diff --git a/gcc/testsuite/gcc.dg/torture/bitint-83.c b/gcc/testsuite/gcc.dg/torture/bitint-83.c new file mode 100644 index 0000000..8a9df44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-83.c @@ -0,0 +1,48 @@ +/* Derived from a test in gcc.dg/torture/bitint-16.c */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +#include "../bitintext.h" + +#define BASIC_TESTS \ + TEST(8) \ + TEST(16) \ + TEST(32) + +#if __BITINT_MAXWIDTH__ >= 519 +#define ALL_TESTS \ + BASIC_TESTS \ + TEST(64) \ + TEST(128) \ + TEST(256) \ + TEST(512) +#else +#define ALL_TESTS BASIC_TESTS +#endif + +#define TEST(N) \ +void \ +test##N (unsigned _BitInt(N + 7) *t, _BitInt(N) x) \ +{ \ + *t = -x; \ +} +ALL_TESTS +#undef TEST + +volatile int y = 0; + +int +main (void) +{ +#define TEST(N) \ + { \ + unsigned _BitInt(N + 7) t; \ + _BitInt(N) x = y + N; \ + test##N (&t, x); \ + BEXTC (t); \ + } + ALL_TESTS +#undef TEST +} diff --git a/gcc/testsuite/gcc.dg/torture/bitint-84.c b/gcc/testsuite/gcc.dg/torture/bitint-84.c new file mode 100644 index 0000000..b3ecbef --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-84.c @@ -0,0 +1,18 @@ +/* A simple variant of gcc.dg/torture/bitint-64.c */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +#include "../bitintext.h" + +enum E : char { E22 = 22 } e = E22; + +int +main () +{ + _Atomic _BitInt (5) b = 0; + b += e; + BEXTC (b); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/bitint-85.c b/gcc/testsuite/gcc.dg/torture/bitint-85.c new file mode 100644 index 0000000..43eb6ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-85.c @@ -0,0 +1,34 @@ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +#if __BITINT_MAXWIDTH__ >= 1024 +constexpr _BitInt(1024) d = -541140097068598424394740839221562143161511518875518765552323978870598341733206554363735813878577506997168480201818027232521wb; +int c; + +static inline void +foo (_BitInt(1024) b, _BitInt(1024) *r) +{ + if (c) + b = 0; + *r = b; +} + +[[gnu::noipa]] void +bar (_BitInt(1024) y) +{ + if (y != d) + __builtin_abort (); +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 1024 + _BitInt(1024) x; + foo (d, &x); + bar (x); +#endif +} 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/vect/vect-gather-1.c b/gcc/testsuite/gcc.dg/vect/vect-gather-1.c index 5f6640d..6497ab4 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-gather-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-gather-1.c @@ -3,9 +3,9 @@ #define N 16 void __attribute__((noipa)) -f (int *restrict y, int *restrict x, int *restrict indices) +f (int *restrict y, int *restrict x, int *restrict indices, int n) { - for (int i = 0; i < N; ++i) + for (int i = 0; i < n; ++i) { y[i * 2] = x[indices[i * 2]] + 1; y[i * 2 + 1] = x[indices[i * 2 + 1]] + 2; @@ -49,7 +49,7 @@ main (void) { check_vect (); - f (y, x, indices); + f (y, x, indices, N); #pragma GCC novector for (int i = 0; i < 32; ++i) if (y[i] != expected[i]) 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/sve/acle/general/cops.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c index f0dc9a9..1201ca0 100644 --- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/cops.c @@ -212,22 +212,22 @@ type init4 = svld1_ ## su ## sz (cmp ## sz, mem); \ \ type res_init1 = func_ ## type ## _init1 (); \ - svbool_t cmp = svcmpne_ ## su ## sz (all_true, init1, res_init1); \ + svbool_t cmp = svcmpne_ ## su ## sz (cmp ## sz, init1, res_init1); \ if (svptest_any (all_true, cmp)) \ __builtin_abort (); \ \ type res_init2 = func_ ## type ## _init2 (); \ - cmp = svcmpne_ ## su ## sz (all_true, init2, res_init2); \ + cmp = svcmpne_ ## su ## sz (cmp ## sz, init2, res_init2); \ if (svptest_any (all_true, cmp)) \ __builtin_abort (); \ \ type res_init3 = func_ ## type ## _init3 (); \ - cmp = svcmpne_ ## su ## sz (all_true, init3, res_init3); \ + cmp = svcmpne_ ## su ## sz (cmp ## sz, init3, res_init3); \ if (svptest_any (all_true, cmp)) \ __builtin_abort (); \ \ type res_init4 = func_ ## type ## _init4 (); \ - cmp = svcmpne_ ## su ## sz (all_true, init4, res_init4); \ + cmp = svcmpne_ ## su ## sz (cmp ## sz, init4, res_init4); \ if (svptest_any (all_true, cmp)) \ __builtin_abort (); \ } diff --git a/gcc/testsuite/gcc.target/riscv/arch-unset-1.c b/gcc/testsuite/gcc.target/riscv/arch-unset-1.c new file mode 100644 index 0000000..971b936 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-unset-1.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i -march=unset -mcpu=sifive-x280 -mabi=lp64 -misa-spec=20191213" } */ +int foo() +{ +} + +/* { dg-final { scan-assembler "\.attribute arch, \"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zfh1p0_zfhmin1p0_zca1p0_zcd1p0_zba1p0_zbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfh1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-unset-2.c b/gcc/testsuite/gcc.target/riscv/arch-unset-2.c new file mode 100644 index 0000000..9840658 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-unset-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i -march=unset -mcpu=sifive-x280 -march=rv64i -mabi=lp64 -misa-spec=20191213" } */ +int foo() +{ +} + +/* { dg-final { scan-assembler "\.attribute arch, \"rv64i2p1\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-unset-3.c b/gcc/testsuite/gcc.target/riscv/arch-unset-3.c new file mode 100644 index 0000000..5ddc224 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-unset-3.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i -march=unset -mcpu=sifive-x280 -march=rv64i -march=unset -mabi=lp64 -misa-spec=20191213" } */ +int foo() +{ +} + +/* { dg-final { scan-assembler "\.attribute arch, \"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_v1p0_zicsr2p0_zmmul1p0_zaamo1p0_zalrsc1p0_zfh1p0_zfhmin1p0_zca1p0_zcd1p0_zba1p0_zbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvfh1p0_zvl128b1p0_zvl256b1p0_zvl32b1p0_zvl512b1p0_zvl64b1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-unset-4.c b/gcc/testsuite/gcc.target/riscv/arch-unset-4.c new file mode 100644 index 0000000..c16821d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-unset-4.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i -march=unset -mcpu=sifive-x280 -march=unset -march=rv64i -march=unset -march=rv64i -mabi=lp64 -misa-spec=20191213" } */ +int foo() +{ +} + +/* { dg-final { scan-assembler "\.attribute arch, \"rv64i2p1\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-unset-5.c b/gcc/testsuite/gcc.target/riscv/arch-unset-5.c new file mode 100644 index 0000000..368c129 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/arch-unset-5.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64i -march=unset -mabi=lp64 -misa-spec=20191213" } */ +int foo() +{ +} + +/* { dg-error "At least one valid -mcpu option must be given after -march=unset" "" { target { "riscv*-*-*" } } 0 } */ diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_2.f03 b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_2.f03 index 79cf2c1..da20835 100644 --- a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_2.f03 +++ b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_2.f03 @@ -1,5 +1,5 @@ ! { dg-do run } -! { dg-additional-sources c_f_pointer_shape_tests_2_driver.c } +! { dg-additional-sources c_f_pointer_shape_tests_driver.c } ! Verify that the optional SHAPE parameter to c_f_pointer can be of any ! valid integer kind. We don't test all kinds here since it would be ! difficult to know what kinds are valid for the architecture we're running on. diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_2_driver.c b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_2_driver.c deleted file mode 100644 index 1282beb..0000000 --- a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_2_driver.c +++ /dev/null @@ -1,46 +0,0 @@ -#define NUM_ELEMS 10 -#define NUM_ROWS 2 -#define NUM_COLS 3 - -void test_long_long_1d(int *array, int num_elems); -void test_long_long_2d(int *array, int num_rows, int num_cols); -void test_long_1d(int *array, int num_elems); -void test_int_1d(int *array, int num_elems); -void test_short_1d(int *array, int num_elems); -void test_mixed(int *array, int num_elems); - -int main(int argc, char **argv) -{ - int my_array[NUM_ELEMS]; - int my_2d_array[NUM_ROWS][NUM_COLS]; - int i, j; - - for(i = 0; i < NUM_ELEMS; i++) - my_array[i] = i; - - for(i = 0; i < NUM_ROWS; i++) - for(j = 0; j < NUM_COLS; j++) - my_2d_array[i][j] = (i*NUM_COLS) + j; - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_long_long. */ - test_long_long_1d(my_array, NUM_ELEMS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_long_long. - The indices are transposed for Fortran. */ - test_long_long_2d(my_2d_array[0], NUM_COLS, NUM_ROWS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_long. */ - test_long_1d(my_array, NUM_ELEMS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_int. */ - test_int_1d(my_array, NUM_ELEMS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_short. */ - test_short_1d(my_array, NUM_ELEMS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_int and - kind=c_long_long. */ - test_mixed(my_array, NUM_ELEMS); - - return 0; -} diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4.f03 b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4.f03 index 3f60f17..519087a 100644 --- a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4.f03 +++ b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4.f03 @@ -1,5 +1,5 @@ ! { dg-do run } -! { dg-additional-sources c_f_pointer_shape_tests_2_driver.c } +! { dg-additional-sources c_f_pointer_shape_tests_driver.c } ! Verify that the optional SHAPE parameter to c_f_pointer can be of any ! valid integer kind. We don't test all kinds here since it would be ! difficult to know what kinds are valid for the architecture we're running on. diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4_driver.c b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4_driver.c deleted file mode 100644 index 1282beb..0000000 --- a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4_driver.c +++ /dev/null @@ -1,46 +0,0 @@ -#define NUM_ELEMS 10 -#define NUM_ROWS 2 -#define NUM_COLS 3 - -void test_long_long_1d(int *array, int num_elems); -void test_long_long_2d(int *array, int num_rows, int num_cols); -void test_long_1d(int *array, int num_elems); -void test_int_1d(int *array, int num_elems); -void test_short_1d(int *array, int num_elems); -void test_mixed(int *array, int num_elems); - -int main(int argc, char **argv) -{ - int my_array[NUM_ELEMS]; - int my_2d_array[NUM_ROWS][NUM_COLS]; - int i, j; - - for(i = 0; i < NUM_ELEMS; i++) - my_array[i] = i; - - for(i = 0; i < NUM_ROWS; i++) - for(j = 0; j < NUM_COLS; j++) - my_2d_array[i][j] = (i*NUM_COLS) + j; - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_long_long. */ - test_long_long_1d(my_array, NUM_ELEMS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_long_long. - The indices are transposed for Fortran. */ - test_long_long_2d(my_2d_array[0], NUM_COLS, NUM_ROWS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_long. */ - test_long_1d(my_array, NUM_ELEMS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_int. */ - test_int_1d(my_array, NUM_ELEMS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_short. */ - test_short_1d(my_array, NUM_ELEMS); - - /* Test c_f_pointer where SHAPE is of type integer, kind=c_int and - kind=c_long_long. */ - test_mixed(my_array, NUM_ELEMS); - - return 0; -} diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_driver.c b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_driver.c new file mode 100644 index 0000000..70e7d56 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_driver.c @@ -0,0 +1,47 @@ +#define NUM_ELEMS 10 +#define NUM_ROWS 2 +#define NUM_COLS 3 + +void test_long_long_1d (int *array, int num_elems); +void test_long_long_2d (int *array, int num_rows, int num_cols); +void test_long_1d (int *array, int num_elems); +void test_int_1d (int *array, int num_elems); +void test_short_1d (int *array, int num_elems); +void test_mixed (int *array, int num_elems); + +int +main (int argc, char **argv) +{ + int my_array[NUM_ELEMS]; + int my_2d_array[NUM_ROWS][NUM_COLS]; + int i, j; + + for (i = 0; i < NUM_ELEMS; i++) + my_array[i] = i; + + for (i = 0; i < NUM_ROWS; i++) + for (j = 0; j < NUM_COLS; j++) + my_2d_array[i][j] = (i * NUM_COLS) + j; + + /* Test c_f_pointer where SHAPE is of type integer, kind=c_long_long. */ + test_long_long_1d (my_array, NUM_ELEMS); + + /* Test c_f_pointer where SHAPE is of type integer, kind=c_long_long. + The indices are transposed for Fortran. */ + test_long_long_2d (my_2d_array[0], NUM_COLS, NUM_ROWS); + + /* Test c_f_pointer where SHAPE is of type integer, kind=c_long. */ + test_long_1d (my_array, NUM_ELEMS); + + /* Test c_f_pointer where SHAPE is of type integer, kind=c_int. */ + test_int_1d (my_array, NUM_ELEMS); + + /* Test c_f_pointer where SHAPE is of type integer, kind=c_short. */ + test_short_1d (my_array, NUM_ELEMS); + + /* Test c_f_pointer where SHAPE is of type integer, kind=c_int and + kind=c_long_long. */ + test_mixed (my_array, NUM_ELEMS); + + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/pr121234.f90 b/gcc/testsuite/gfortran.dg/pr121234.f90 new file mode 100644 index 0000000..8eb1af53 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr121234.f90 @@ -0,0 +1,28 @@ +! { dg-do run } +! PR121234 Bogus diagnostic on READ of string with semicolon. + character(12) buffer,a + a = 'xxxxxxxxxx' + buffer="33;44" + read(buffer,*) a + if (a .ne. "33;44") stop 1 + a = 'xxxxxxxxxx' + buffer=" ;;33 ,44 " + read(buffer,*,decimal="comma") a + if (a .ne. 'xxxxxxxxxx') stop 2 ! A null read + a = 'xxxxxxxxxx' + buffer=" ;;33 ,44 " + read(buffer,*,decimal="point") a + if (a .ne. ';;33') stop 3 ! Spaces are delimiting + a = 'xxxxxxxxxx' + buffer=";;33;,44 " + read(buffer,*) a + if (a .ne. ';;33;') stop 4 ! Comma is delimiting + a = 'xxxxxxxxxx' + buffer=";;33;44;; " + read(buffer,*) a + if (a .ne. ';;33;44;;') stop 5 ! Space is delimiting + a = 'xxxxxxxxxx' + buffer=";;33;44;;;.7" + read(buffer,*) a + if (a .ne. ';;33;44;;;.7') stop 6 ! Space is delimiting +end diff --git a/gcc/tree-nested.cc b/gcc/tree-nested.cc index 8d75a2f..813334b 100644 --- a/gcc/tree-nested.cc +++ b/gcc/tree-nested.cc @@ -1796,6 +1796,8 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, break; case GIMPLE_OMP_TARGET: + walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, + info, gimple_omp_target_iterator_loops_ptr (stmt)); if (!is_gimple_omp_offloaded (stmt)) { save_suppress = info->suppress_expansion; @@ -2517,6 +2519,9 @@ convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, break; case GIMPLE_OMP_TARGET: + walk_body (convert_local_reference_stmt, convert_local_reference_op, info, + gimple_omp_target_iterator_loops_ptr (stmt)); + if (!is_gimple_omp_offloaded (stmt)) { save_suppress = info->suppress_expansion; @@ -2898,6 +2903,8 @@ convert_tramp_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, *handled_ops_p = false; return NULL_TREE; } + walk_body (convert_tramp_reference_stmt, convert_tramp_reference_op, + info, gimple_omp_target_iterator_loops_ptr (stmt)); /* FALLTHRU */ case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc index 50d0851..c19baba 100644 --- a/gcc/tree-pretty-print.cc +++ b/gcc/tree-pretty-print.cc @@ -448,6 +448,15 @@ dump_omp_iterators (pretty_printer *pp, tree iter, int spc, dump_flags_t flags) pp_colon (pp); dump_generic_node (pp, TREE_VEC_ELT (it, 3), spc, flags, false); } + if (TREE_VEC_LENGTH (iter) > 6) + { + pp_string (pp, ", loop_label="); + dump_generic_node (pp, TREE_VEC_ELT (iter, 6), spc, flags, false); + pp_string (pp, ", elems="); + dump_generic_node (pp, TREE_VEC_ELT (iter, 7), spc, flags, false); + pp_string (pp, ", index="); + dump_generic_node (pp, TREE_VEC_ELT (iter, 8), spc, flags, false); + } pp_right_paren (pp); } @@ -1008,6 +1017,11 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) pp_string (pp, "map("); if (OMP_CLAUSE_MAP_READONLY (clause)) pp_string (pp, "readonly,"); + if (OMP_CLAUSE_ITERATORS (clause)) + { + dump_omp_iterators (pp, OMP_CLAUSE_ITERATORS (clause), spc, flags); + pp_colon (pp); + } switch (OMP_CLAUSE_MAP_KIND (clause)) { case GOMP_MAP_ALLOC: @@ -1185,6 +1199,11 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) pp_string (pp, "from("); if (OMP_CLAUSE_MOTION_PRESENT (clause)) pp_string (pp, "present:"); + if (OMP_CLAUSE_ITERATORS (clause)) + { + dump_omp_iterators (pp, OMP_CLAUSE_ITERATORS (clause), spc, flags); + pp_colon (pp); + } dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); goto print_clause_size; @@ -1193,6 +1212,11 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) pp_string (pp, "to("); if (OMP_CLAUSE_MOTION_PRESENT (clause)) pp_string (pp, "present:"); + if (OMP_CLAUSE_ITERATORS (clause)) + { + dump_omp_iterators (pp, OMP_CLAUSE_ITERATORS (clause), spc, flags); + pp_colon (pp); + } dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); goto print_clause_size; diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc index dc82bf6..a9d4aae 100644 --- a/gcc/tree-vect-data-refs.cc +++ b/gcc/tree-vect-data-refs.cc @@ -4423,8 +4423,9 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo) MASKED_P is true if the load or store is conditional. MEMORY_TYPE is the type of the memory elements being loaded or stored. OFFSET_TYPE is the type of the offset that is being applied to the invariant - base address. SCALE is the amount by which the offset should - be multiplied *after* it has been converted to address width. + base address. If OFFSET_TYPE is scalar the function chooses an + appropriate vector type for it. SCALE is the amount by which the + offset should be multiplied *after* it has been converted to address width. Return true if the function is supported, storing the function id in *IFN_OUT and the vector type for the offset in *OFFSET_VECTYPE_OUT. @@ -4467,9 +4468,15 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p, bool masked_p, for (;;) { - tree offset_vectype = get_vectype_for_scalar_type (vinfo, offset_type); - if (!offset_vectype) - return false; + tree offset_vectype; + if (VECTOR_TYPE_P (offset_type)) + offset_vectype = offset_type; + else + { + offset_vectype = get_vectype_for_scalar_type (vinfo, offset_type); + if (!offset_vectype) + return false; + } /* Test whether the target supports this combination. */ if (internal_gather_scatter_fn_supported_p (ifn, vectype, memory_type, @@ -4500,10 +4507,15 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p, bool masked_p, return true; } + /* For fixed offset vector type we're done. */ + if (VECTOR_TYPE_P (offset_type)) + return false; + if (TYPE_PRECISION (offset_type) >= POINTER_SIZE && TYPE_PRECISION (offset_type) >= element_bits) return false; + /* Try a larger offset vector type. */ offset_type = build_nonstandard_integer_type (TYPE_PRECISION (offset_type) * 2, TYPE_UNSIGNED (offset_type)); } @@ -4512,7 +4524,7 @@ vect_gather_scatter_fn_p (vec_info *vinfo, bool read_p, bool masked_p, /* STMT_INFO is a call to an internal gather load or scatter store function. Describe the operation in INFO. */ -static void +void vect_describe_gather_scatter_call (stmt_vec_info stmt_info, gather_scatter_info *info) { @@ -6524,7 +6536,7 @@ vect_supportable_dr_alignment (vec_info *vinfo, dr_vec_info *dr_info, tree vectype, int misalignment, gather_scatter_info *gs_info) { - data_reference *dr = dr_info ? dr_info->dr : nullptr; + data_reference *dr = dr_info->dr; stmt_vec_info stmt_info = dr_info->stmt; machine_mode mode = TYPE_MODE (vectype); loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo); @@ -6605,7 +6617,7 @@ vect_supportable_dr_alignment (vec_info *vinfo, dr_vec_info *dr_info, } } */ - if (dr && DR_IS_READ (dr)) + if (DR_IS_READ (dr)) { if (can_implement_p (vec_realign_load_optab, mode) && (!targetm.vectorize.builtin_mask_for_load @@ -6635,38 +6647,7 @@ vect_supportable_dr_alignment (vec_info *vinfo, dr_vec_info *dr_info, tree type = TREE_TYPE (DR_REF (dr)); bool is_gather_scatter = gs_info != nullptr; if (misalignment == DR_MISALIGNMENT_UNKNOWN) - { - if (!is_gather_scatter || dr != nullptr) - is_packed = not_size_aligned (DR_REF (dr)); - else - { - /* Gather-scatter accesses normally perform only component accesses - so alignment is irrelevant for them. Targets like riscv do care - about scalar alignment in vector accesses, though, so check scalar - alignment here. We determined the alias pointer as well as the - base alignment during pattern recognition and can re-use it here. - - As we do not have an analyzed dataref we only know the alignment - of the reference itself and nothing about init, steps, etc. - For now don't try harder to determine misalignment and - just assume it is unknown. We consider the type packed if its - scalar alignment is lower than the natural alignment of a vector - element's type. */ - - gcc_assert (!GATHER_SCATTER_LEGACY_P (*gs_info)); - gcc_assert (dr == nullptr); - - tree inner_vectype = TREE_TYPE (vectype); - - unsigned HOST_WIDE_INT scalar_align - = tree_to_uhwi (gs_info->alias_ptr); - unsigned HOST_WIDE_INT inner_vectype_sz - = tree_to_uhwi (TYPE_SIZE (inner_vectype)); - - bool is_misaligned = scalar_align < inner_vectype_sz; - is_packed = scalar_align > 1 && is_misaligned; - } - } + is_packed = not_size_aligned (DR_REF (dr)); if (targetm.vectorize.support_vector_misalignment (mode, type, misalignment, is_packed, is_gather_scatter)) diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 794a073..59acbc1 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -120,6 +120,8 @@ _slp_tree::_slp_tree () SLP_TREE_LANE_PERMUTATION (this) = vNULL; SLP_TREE_DEF_TYPE (this) = vect_uninitialized_def; SLP_TREE_CODE (this) = ERROR_MARK; + SLP_TREE_GS_SCALE (this) = 0; + SLP_TREE_GS_BASE (this) = NULL_TREE; this->ldst_lanes = false; this->avoid_stlf_fail = false; SLP_TREE_VECTYPE (this) = NULL_TREE; @@ -680,6 +682,15 @@ vect_get_and_check_slp_defs (vec_info *vinfo, unsigned char swap, { internal_fn ifn = gimple_call_internal_fn (stmt); commutative_op = first_commutative_argument (ifn); + if (internal_gather_scatter_fn_p (ifn)) + { + vect_describe_gather_scatter_call + (stmt_info, + first ? &(*oprnds_info)[0]->first_gs_info : &gs_info); + if (first) + (*oprnds_info)[0]->first_gs_p = true; + gs_op = 0; + } } } else if (gassign *stmt = dyn_cast <gassign *> (stmt_info->stmt)) @@ -2720,6 +2731,9 @@ out: stmt_info = stmts[0]; + int gs_scale = 0; + tree gs_base = NULL_TREE; + /* Create SLP_TREE nodes for the definition node/s. */ FOR_EACH_VEC_ELT (oprnds_info, i, oprnd_info) { @@ -2742,6 +2756,12 @@ out: continue; } + if (oprnd_info->first_gs_p) + { + gs_scale = oprnd_info->first_gs_info.scale; + gs_base = oprnd_info->first_gs_info.base; + } + if (is_a <bb_vec_info> (vinfo) && oprnd_info->first_dt == vect_internal_def && !oprnd_info->any_pattern) @@ -3131,6 +3151,8 @@ fail: node = vect_create_new_slp_node (node, stmts, nops); SLP_TREE_VECTYPE (node) = vectype; SLP_TREE_CHILDREN (node).splice (children); + SLP_TREE_GS_SCALE (node) = gs_scale; + SLP_TREE_GS_BASE (node) = gs_base; return node; } diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index f7a052b..a6f4db4 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -1497,7 +1497,8 @@ check_load_store_for_partial_vectors (loop_vec_info loop_vinfo, tree vectype, gs_info->memory_type, gs_info->offset_vectype, gs_info->scale, - elsvals)) + elsvals) + || gs_info->decl != NULL_TREE) vect_record_loop_mask (loop_vinfo, masks, nvectors, vectype, scalar_mask); else @@ -2018,31 +2019,40 @@ get_load_store_type (vec_info *vinfo, stmt_vec_info stmt_info, else if (STMT_VINFO_GATHER_SCATTER_P (stmt_info)) { *memory_access_type = VMAT_GATHER_SCATTER; - if (!vect_check_gather_scatter (stmt_info, loop_vinfo, gs_info, - elsvals)) - gcc_unreachable (); slp_tree offset_node = SLP_TREE_CHILDREN (slp_node)[0]; tree offset_vectype = SLP_TREE_VECTYPE (offset_node); + memset (gs_info, 0, sizeof (gather_scatter_info)); gs_info->offset_vectype = offset_vectype; - /* When using internal functions, we rely on pattern recognition - to convert the type of the offset to the type that the target - requires, with the result being a call to an internal function. - If that failed for some reason (e.g. because another pattern - took priority), just handle cases in which the offset already - has the right type. */ - if (GATHER_SCATTER_IFN_P (*gs_info) - && !is_gimple_call (stmt_info->stmt) - && !tree_nop_conversion_p (TREE_TYPE (gs_info->offset), - TREE_TYPE (offset_vectype))) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "%s offset requires a conversion\n", - vls_type == VLS_LOAD ? "gather" : "scatter"); - return false; - } - else if (GATHER_SCATTER_EMULATED_P (*gs_info)) + gs_info->scale = SLP_TREE_GS_SCALE (slp_node); + gs_info->base = SLP_TREE_GS_BASE (slp_node); + gs_info->memory_type = TREE_TYPE (DR_REF (first_dr_info->dr)); + gs_info->decl = NULL_TREE; + gs_info->ifn = IFN_LAST; + tree tem; + if (vect_gather_scatter_fn_p (loop_vinfo, vls_type == VLS_LOAD, + masked_p, vectype, + gs_info->memory_type, + offset_vectype, gs_info->scale, + &gs_info->ifn, &tem, + elsvals)) + /* GATHER_SCATTER_IFN_P. */; + else if (vls_type == VLS_LOAD + ? (targetm.vectorize.builtin_gather + && (gs_info->decl + = targetm.vectorize.builtin_gather (vectype, + TREE_TYPE + (offset_vectype), + gs_info->scale))) + : (targetm.vectorize.builtin_scatter + && (gs_info->decl + = targetm.vectorize.builtin_scatter (vectype, + TREE_TYPE + (offset_vectype), + gs_info->scale)))) + /* GATHER_SCATTER_LEGACY_P. */; + else { + /* GATHER_SCATTER_EMULATED_P. */ if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant () || !TYPE_VECTOR_SUBPARTS (offset_vectype).is_constant () || VECTOR_BOOLEAN_TYPE_P (offset_vectype) @@ -8529,7 +8539,6 @@ vectorizable_store (vec_info *vinfo, gcc_assert (useless_type_conversion_p (vectype, TREE_TYPE (vec_oprnd))); } - unsigned HOST_WIDE_INT align; tree final_mask = NULL_TREE; tree final_len = NULL_TREE; tree bias = NULL_TREE; @@ -8544,6 +8553,8 @@ vectorizable_store (vec_info *vinfo, final_mask, vec_mask, gsi); } + unsigned align = get_object_alignment (DR_REF (first_dr_info->dr)); + tree alias_align_ptr = build_int_cst (ref_type, align); if (GATHER_SCATTER_IFN_P (gs_info)) { if (costing_p) @@ -8585,7 +8596,7 @@ vectorizable_store (vec_info *vinfo, if (VECTOR_TYPE_P (TREE_TYPE (vec_offset))) call = gimple_build_call_internal ( IFN_MASK_LEN_SCATTER_STORE, 8, dataref_ptr, - gs_info.alias_ptr, + alias_align_ptr, vec_offset, scale, vec_oprnd, final_mask, final_len, bias); else @@ -8602,12 +8613,12 @@ vectorizable_store (vec_info *vinfo, else if (final_mask) call = gimple_build_call_internal (IFN_MASK_SCATTER_STORE, 6, dataref_ptr, - gs_info.alias_ptr, + alias_align_ptr, vec_offset, scale, vec_oprnd, final_mask); else call = gimple_build_call_internal (IFN_SCATTER_STORE, 5, dataref_ptr, - gs_info.alias_ptr, + alias_align_ptr, vec_offset, scale, vec_oprnd); gimple_call_set_nothrow (call, true); @@ -8763,7 +8774,6 @@ vectorizable_store (vec_info *vinfo, = (j % factor) * const_nunits; tree idx_type = TREE_TYPE (TREE_TYPE (vec_offset)); tree scale = size_int (gs_info.scale); - align = get_object_alignment (DR_REF (first_dr_info->dr)); tree ltype = build_aligned_type (TREE_TYPE (vectype), align); for (unsigned k = 0; k < const_nunits; ++k) { @@ -10392,7 +10402,8 @@ vectorizable_load (vec_info *vinfo, } /* 2. Create the vector-load in the loop. */ - unsigned HOST_WIDE_INT align; + unsigned align = get_object_alignment (DR_REF (first_dr_info->dr)); + tree alias_align_ptr = build_int_cst (ref_type, align); if (GATHER_SCATTER_IFN_P (gs_info)) { if (costing_p) @@ -10440,7 +10451,7 @@ vectorizable_load (vec_info *vinfo, if (VECTOR_TYPE_P (TREE_TYPE (vec_offset))) call = gimple_build_call_internal (IFN_MASK_LEN_GATHER_LOAD, 9, dataref_ptr, - gs_info.alias_ptr, + alias_align_ptr, vec_offset, scale, zero, final_mask, vec_els, final_len, bias); @@ -10456,13 +10467,13 @@ vectorizable_load (vec_info *vinfo, else if (final_mask) call = gimple_build_call_internal (IFN_MASK_GATHER_LOAD, 7, dataref_ptr, - gs_info.alias_ptr, + alias_align_ptr, vec_offset, scale, zero, final_mask, vec_els); else call = gimple_build_call_internal (IFN_GATHER_LOAD, 5, dataref_ptr, - gs_info.alias_ptr, + alias_align_ptr, vec_offset, scale, zero); gimple_call_set_nothrow (call, true); new_stmt = call; @@ -10620,7 +10631,6 @@ vectorizable_load (vec_info *vinfo, unsigned elt_offset = (i % factor) * const_nunits; tree idx_type = TREE_TYPE (TREE_TYPE (vec_offset)); tree scale = size_int (gs_info.scale); - align = get_object_alignment (DR_REF (first_dr_info->dr)); tree ltype = build_aligned_type (TREE_TYPE (vectype), align); for (unsigned k = 0; k < const_nunits; ++k) { diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 52e1075..9653496 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -306,6 +306,11 @@ struct _slp_tree { unsigned int lanes; /* The operation of this node. */ enum tree_code code; + /* For gather/scatter memory operations the scale each offset element + should be multiplied by before being added to the base. */ + int gs_scale; + /* For gather/scatter memory operations the loop-invariant base value. */ + tree gs_base; /* Whether uses of this load or feeders of this store are suitable for load/store-lanes. */ bool ldst_lanes; @@ -412,6 +417,8 @@ public: #define SLP_TREE_CODE(S) (S)->code #define SLP_TREE_MEMORY_ACCESS_TYPE(S) (S)->memory_access_type #define SLP_TREE_TYPE(S) (S)->type +#define SLP_TREE_GS_SCALE(S) (S)->gs_scale +#define SLP_TREE_GS_BASE(S) (S)->gs_base enum vect_partial_vector_style { vect_partial_vectors_none, @@ -2550,6 +2557,8 @@ extern bool vect_gather_scatter_fn_p (vec_info *, bool, bool, tree, tree, extern bool vect_check_gather_scatter (stmt_vec_info, loop_vec_info, gather_scatter_info *, vec<int> * = nullptr); +extern void vect_describe_gather_scatter_call (stmt_vec_info, + gather_scatter_info *); extern opt_result vect_find_stmt_data_reference (loop_p, gimple *, vec<data_reference_p> *, vec<int> *, int); diff --git a/gcc/tree.cc b/gcc/tree.cc index 0f02924..dcc1abd 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -323,9 +323,9 @@ unsigned const char omp_clause_num_ops[] = 1, /* OMP_CLAUSE_IS_DEVICE_PTR */ 1, /* OMP_CLAUSE_INCLUSIVE */ 1, /* OMP_CLAUSE_EXCLUSIVE */ - 2, /* OMP_CLAUSE_FROM */ - 2, /* OMP_CLAUSE_TO */ - 2, /* OMP_CLAUSE_MAP */ + 3, /* OMP_CLAUSE_FROM */ + 3, /* OMP_CLAUSE_TO */ + 3, /* OMP_CLAUSE_MAP (update walk_tree_1 if this is changed) */ 1, /* OMP_CLAUSE_HAS_DEVICE_ADDR */ 1, /* OMP_CLAUSE_DOACROSS */ 3, /* OMP_CLAUSE__MAPPER_BINDING_ */ @@ -11769,6 +11769,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE: { int len = omp_clause_num_ops[OMP_CLAUSE_CODE (t)]; + /* Do not walk the iterator operand of OpenMP MAP clauses. */ + if (OMP_CLAUSE_HAS_ITERATORS (t)) + len--; for (int i = 0; i < len; i++) WALK_SUBTREE (OMP_CLAUSE_OPERAND (t, i)); WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (t)); @@ -1659,6 +1659,16 @@ class auto_suppress_location_wrappers != UNKNOWN_LOCATION) #define OMP_CLAUSE_LOCATION(NODE) (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus +#define OMP_CLAUSE_HAS_ITERATORS(NODE) \ + ((OMP_CLAUSE_CODE (NODE) == OMP_CLAUSE_FROM \ + || OMP_CLAUSE_CODE (NODE) == OMP_CLAUSE_TO \ + || OMP_CLAUSE_CODE (NODE) == OMP_CLAUSE_MAP) \ + && OMP_CLAUSE_ITERATORS (NODE)) +#define OMP_CLAUSE_ITERATORS(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \ + OMP_CLAUSE_FROM, \ + OMP_CLAUSE_MAP), 2) + /* True on OMP_FOR and other OpenMP/OpenACC looping constructs if the loop nest is non-rectangular. */ #define OMP_FOR_NON_RECTANGULAR(NODE) \ diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index e58fad1..7deda4b 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,9 @@ +2025-08-05 Jakub Jelinek <jakub@redhat.com> + + PR preprocessor/120778 + * macro.cc (paste_tokens): Use %< and %> instead of \" in + diagnostics around %.*s. + 2025-08-04 Jakub Jelinek <jakub@redhat.com> PR preprocessor/120778 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/enable-execute-stack-mprotect.c b/libgcc/enable-execute-stack-mprotect.c index 08a0d72..7971efb 100644 --- a/libgcc/enable-execute-stack-mprotect.c +++ b/libgcc/enable-execute-stack-mprotect.c @@ -30,7 +30,6 @@ static int need_enable_exec_stack; -static void check_enabling (void) __attribute__ ((unused)); extern void __enable_execute_stack (void *); #if defined __sun__ && defined __svr4__ 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/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index 83124b5..7c22f61 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -1262,6 +1262,11 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused))) if ((c = next_char (dtp)) == EOF) goto eof; + if (c == ';') + { + push_char (dtp, c); + goto get_string; + } switch (c) { CASE_DIGITS: @@ -1294,6 +1299,13 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused))) for (;;) { c = next_char (dtp); + + if (c == ';') + { + push_char (dtp, c); + goto get_string; + } + switch (c) { CASE_DIGITS: @@ -1323,6 +1335,13 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused))) if ((c = next_char (dtp)) == EOF) goto eof; + + if (c == ';') + { + push_char (dtp, c); + goto get_string; + } + switch (c) { CASE_SEPARATORS: @@ -1346,6 +1365,13 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused))) { if ((c = next_char (dtp)) == EOF) goto done_eof; + + if (c == ';') + { + push_char (dtp, c); + continue; + } + switch (c) { case '"': @@ -2275,6 +2301,8 @@ list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p, } if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA) c = '.'; + if (c == ';' && dtp->u.p.current_unit->decimal_status == DECIMAL_POINT) + unget_char (dtp, c); else if (is_separator (c)) { /* Found a null value. */ 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/libgomp/target.c b/libgomp/target.c index cda092b..c89c82c 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -1003,6 +1003,155 @@ gomp_map_val (struct target_mem_desc *tgt, void **hostaddrs, size_t i) } } +static const char * +kind_to_name (unsigned short kind, bool short_mapkind) +{ + if (short_mapkind && GOMP_MAP_IMPLICIT_P (kind)) + kind &= ~GOMP_MAP_IMPLICIT; + + switch (kind & (short_mapkind ? 0xff : 0x7)) + { + case GOMP_MAP_ALLOC: return "GOMP_MAP_ALLOC"; + case GOMP_MAP_TO: return "GOMP_MAP_TO"; + case GOMP_MAP_FROM: return "GOMP_MAP_FROM"; + case GOMP_MAP_TOFROM: return "GOMP_MAP_TOFROM"; + case GOMP_MAP_POINTER: return "GOMP_MAP_POINTER"; + case GOMP_MAP_TO_PSET: return "GOMP_MAP_TO_PSET"; + case GOMP_MAP_FORCE_PRESENT: return "GOMP_MAP_FORCE_PRESENT"; + case GOMP_MAP_DELETE: return "GOMP_MAP_DELETE"; + case GOMP_MAP_FORCE_DEVICEPTR: return "GOMP_MAP_FORCE_DEVICEPTR"; + case GOMP_MAP_DEVICE_RESIDENT: return "GOMP_MAP_DEVICE_RESIDENT"; + case GOMP_MAP_LINK: return "GOMP_MAP_LINK"; + case GOMP_MAP_IF_PRESENT: return "GOMP_MAP_IF_PRESENT"; + case GOMP_MAP_FIRSTPRIVATE: return "GOMP_MAP_FIRSTPRIVATE"; + case GOMP_MAP_FIRSTPRIVATE_INT: return "GOMP_MAP_FIRSTPRIVATE_INT"; + case GOMP_MAP_USE_DEVICE_PTR: return "GOMP_MAP_USE_DEVICE_PTR"; + case GOMP_MAP_ZERO_LEN_ARRAY_SECTION: return "GOMP_MAP_ZERO_LEN_ARRAY_SECTION"; + case GOMP_MAP_FORCE_ALLOC: return "GOMP_MAP_FORCE_ALLOC"; + case GOMP_MAP_FORCE_TO: return "GOMP_MAP_FORCE_TO"; + case GOMP_MAP_FORCE_FROM: return "GOMP_MAP_FORCE_FROM"; + case GOMP_MAP_FORCE_TOFROM: return "GOMP_MAP_FORCE_TOFROM"; + case GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT: + return "GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT"; + case GOMP_MAP_ALWAYS_TO: return "GOMP_MAP_ALWAYS_TO"; + case GOMP_MAP_ALWAYS_FROM: return "GOMP_MAP_ALWAYS_FROM"; + case GOMP_MAP_ALWAYS_TOFROM: return "GOMP_MAP_ALWAYS_TOFROM"; + case GOMP_MAP_ALWAYS_PRESENT_TO: return "GOMP_MAP_ALWAYS_PRESENT_TO"; + case GOMP_MAP_ALWAYS_PRESENT_FROM: return "GOMP_MAP_ALWAYS_PRESENT_FROM"; + case GOMP_MAP_ALWAYS_PRESENT_TOFROM: return "GOMP_MAP_ALWAYS_PRESENT_TOFROM"; + case GOMP_MAP_STRUCT: return "GOMP_MAP_STRUCT"; + case GOMP_MAP_STRUCT_UNORD: return "GOMP_MAP_STRUCT_UNORD"; + case GOMP_MAP_ALWAYS_POINTER: return "GOMP_MAP_ALWAYS_POINTER"; + case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION: + return "GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION"; + case GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION: + return "GOMP_MAP_DELETE_ZERO_LENGTH_ARRAY_SECTION"; + case GOMP_MAP_RELEASE: return "GOMP_MAP_RELEASE"; + case GOMP_MAP_ATTACH: return "GOMP_MAP_ATTACH"; + case GOMP_MAP_DETACH: return "GOMP_MAP_DETACH"; + case GOMP_MAP_FORCE_DETACH: return "GOMP_MAP_FORCE_DETACH"; + case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION: + return "GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION"; + default: return "unknown"; + } +} + +/* When GCC encounters a clause with an iterator, e.g.: + + #pragma omp target map (iterator(i=0:4), to: x[i]) + + it generates an array containing the number of iterations and the + address and size of each iteration. e.g.: + + void *omp_iter_data[] = { + (void *) 4, // Number of iterations + &x[0], (void *) sizeof(x[0]), + &x[1], (void *) sizeof(x[1]), + &x[2], (void *) sizeof(x[2]), + &x[3], (void *) sizeof(x[3]) + }; + + When the construct is lowered, &omp_iter_data is used as the host address + for the map (instead of &x[i]), and the size is set to SIZE_MAX to mark + the map as an iterator map. + + Map entries containing expanded iterators will be flattened and merged into + HOSTADDRS, SIZES and KINDS, and MAPNUM updated. Returns true if there are + any iterators found. ITERATOR_COUNT holds the iteration count of the + iterator that generates each map (and 0 if not generated from an iterator). + HOSTADDRS, SIZES, KINDS and ITERATOR_COUNT must be freed afterwards if any + merging occurs. */ + +static bool +gomp_merge_iterator_maps (size_t *mapnum, void ***hostaddrs, size_t **sizes, + void **kinds, size_t **iterator_count) +{ + bool iterator_p = false; + size_t map_count = 0; + unsigned short **skinds = (unsigned short **) kinds; + + for (size_t i = 0; i < *mapnum; i++) + if ((*sizes)[i] == SIZE_MAX) + { + uintptr_t *iterator_array = (*hostaddrs)[i]; + map_count += iterator_array[0]; + iterator_p = true; + } + else + map_count++; + + if (!iterator_p) + return false; + + gomp_debug (1, + "Expanding iterator maps - number of map entries: %u -> %u\n", + (int) *mapnum, (int) map_count); + void **new_hostaddrs = (void **) gomp_malloc (map_count * sizeof (void *)); + size_t *new_sizes = (size_t *) gomp_malloc (map_count * sizeof (size_t)); + unsigned short *new_kinds + = (unsigned short *) gomp_malloc (map_count * sizeof (unsigned short)); + size_t new_idx = 0; + *iterator_count = (size_t *) gomp_malloc (map_count * sizeof (size_t)); + + for (size_t i = 0; i < *mapnum; i++) + { + if ((*sizes)[i] == SIZE_MAX) + { + uintptr_t *iterator_array = (*hostaddrs)[i]; + size_t count = *iterator_array++; + for (size_t j = 0; j < count; j++) + { + new_hostaddrs[new_idx] = (void *) *iterator_array++; + new_sizes[new_idx] = *iterator_array++; + new_kinds[new_idx] = (*skinds)[i]; + (*iterator_count)[new_idx] = j + 1; + gomp_debug (1, + "Expanding map %u <%s>: " + "hostaddrs[%u] = %p, sizes[%u] = %lu\n", + (int) i, kind_to_name (new_kinds[new_idx], true), + (int) new_idx, new_hostaddrs[new_idx], + (int) new_idx, (unsigned long) new_sizes[new_idx]); + new_idx++; + } + } + else + { + new_hostaddrs[new_idx] = (*hostaddrs)[i]; + new_sizes[new_idx] = (*sizes)[i]; + new_kinds[new_idx] = (*skinds)[i]; + (*iterator_count)[new_idx] = 0; + new_idx++; + } + } + + *mapnum = map_count; + *hostaddrs = new_hostaddrs; + *sizes = new_sizes; + *kinds = new_kinds; + + return true; +} + static inline __attribute__((always_inline)) struct target_mem_desc * gomp_map_vars_internal (struct gomp_device_descr *devicep, struct goacc_asyncqueue *aq, size_t mapnum, @@ -1019,6 +1168,11 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep, const int typemask = short_mapkind ? 0xff : 0x7; struct splay_tree_s *mem_map = &devicep->mem_map; struct splay_tree_key_s cur_node; + bool iterators_p = false; + size_t *iterator_count = NULL; + if (short_mapkind) /* OpenMP */ + iterators_p = gomp_merge_iterator_maps (&mapnum, &hostaddrs, &sizes, + &kinds, &iterator_count); struct target_mem_desc *tgt = gomp_malloc (sizeof (*tgt) + sizeof (tgt->list[0]) * mapnum); tgt->list_count = mapnum; @@ -1896,14 +2050,22 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep, if (pragma_kind & GOMP_MAP_VARS_TARGET) { + /* The target variables table is constructed with maps using iterators + unexpanded. Now that the iterator maps are expanded, we will need to + skip all expanded maps after the initial entry, otherwise subsequent + maps will be out-of-sync with their corresponding entry in the + target variables table. */ + size_t map_num = 0; for (i = 0; i < mapnum; i++) - { - cur_node.tgt_offset = gomp_map_val (tgt, hostaddrs, i); - gomp_copy_host2dev (devicep, aq, - (void *) (tgt->tgt_start + i * sizeof (void *)), - (void *) &cur_node.tgt_offset, sizeof (void *), - true, cbufp); - } + if (!iterator_count || iterator_count[i] <= 1) + { + cur_node.tgt_offset = gomp_map_val (tgt, hostaddrs, i); + gomp_copy_host2dev (devicep, aq, + (void *) (tgt->tgt_start + map_num * sizeof (void *)), + (void *) &cur_node.tgt_offset, sizeof (void *), + true, cbufp); + map_num++; + } } if (cbufp) @@ -1935,6 +2097,15 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep, } gomp_mutex_unlock (&devicep->lock); + + if (iterators_p) + { + free (hostaddrs); + free (sizes); + free (kinds); + free (iterator_count); + } + return tgt; } @@ -2201,6 +2372,8 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs, size_t i; struct splay_tree_key_s cur_node; const int typemask = short_mapkind ? 0xff : 0x7; + bool iterators_p = false; + size_t *iterator_count = NULL; if (!devicep) return; @@ -2208,6 +2381,10 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs, if (mapnum == 0) return; + if (short_mapkind) /* OpenMP */ + iterators_p = gomp_merge_iterator_maps (&mapnum, &hostaddrs, &sizes, + &kinds, &iterator_count); + gomp_mutex_lock (&devicep->lock); if (devicep->state == GOMP_DEVICE_FINALIZED) { @@ -2301,6 +2478,14 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs, } } gomp_mutex_unlock (&devicep->lock); + + if (iterators_p) + { + free (hostaddrs); + free (sizes); + free (kinds); + free (iterator_count); + } } static struct gomp_offload_icv_list * diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-1.c b/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-1.c new file mode 100644 index 0000000..b3d87f2 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-1.c @@ -0,0 +1,47 @@ +/* { dg-do run } */ +/* { dg-require-effective-target offload_device_nonshared_as } */ + +/* Test transfer of dynamically-allocated arrays to target using map + iterators. */ + +#include <stdlib.h> + +#define DIM1 8 +#define DIM2 15 + +int mkarray (int *x[]) +{ + int expected = 0; + + for (int i = 0; i < DIM1; i++) + { + x[i] = (int *) malloc (DIM2 * sizeof (int)); + for (int j = 0; j < DIM2; j++) + { + x[i][j] = rand (); + expected += x[i][j]; + } + } + + return expected; +} + +int main (void) +{ + int *x[DIM1]; + int y; + + int expected = mkarray (x); + + #pragma omp target enter data map(to: x) + #pragma omp target map(iterator(i=0:DIM1), to: x[i][:DIM2]) \ + map(from: y) + { + y = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + y += x[i][j]; + } + + return y - expected; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-2.c b/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-2.c new file mode 100644 index 0000000..8569b55 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-2.c @@ -0,0 +1,44 @@ +/* { dg-do run } */ +/* { dg-require-effective-target offload_device_nonshared_as } */ + +/* Test transfer of dynamically-allocated arrays from target using map + iterators. */ + +#include <stdlib.h> + +#define DIM1 8 +#define DIM2 15 + +void mkarray (int *x[]) +{ + for (int i = 0; i < DIM1; i++) + x[i] = (int *) malloc (DIM2 * sizeof (int)); +} + +int main (void) +{ + int *x[DIM1]; + int y, expected; + + mkarray (x); + + #pragma omp target enter data map(alloc: x) + #pragma omp target map(iterator(i=0:DIM1), from: x[i][:DIM2]) \ + map(from: expected) + { + expected = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + { + x[i][j] = (i+1) * (j+1); + expected += x[i][j]; + } + } + + y = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + y += x[i][j]; + + return y - expected; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-3.c b/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-3.c new file mode 100644 index 0000000..be30fa65d --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/target-map-iterators-3.c @@ -0,0 +1,56 @@ +/* { dg-do run } */ +/* { dg-require-effective-target offload_device_nonshared_as } */ + +/* Test transfer of dynamically-allocated arrays to target using map + iterators, with multiple iterators and function calls in the iterator + expression. */ + +#include <stdlib.h> + +#define DIM1 16 +#define DIM2 15 + +int mkarrays (int *x[], int *y[]) +{ + int expected = 0; + + for (int i = 0; i < DIM1; i++) + { + x[i] = (int *) malloc (DIM2 * sizeof (int)); + y[i] = (int *) malloc (sizeof (int)); + *y[i] = rand (); + for (int j = 0; j < DIM2; j++) + { + x[i][j] = rand (); + expected += x[i][j] * *y[i]; + } + } + + return expected; +} + +int f (int i, int j) +{ + return i * 4 + j; +} + +int main (void) +{ + int *x[DIM1], *y[DIM1]; + int sum; + + int expected = mkarrays (x, y); + + #pragma omp target enter data map(to: x, y) + #pragma omp target map(iterator(i=0:DIM1/4, j=0:4), to: x[f(i, j)][:DIM2]) \ + map(iterator(i=0:DIM1), to: y[i][:1]) \ + map(from: sum) + { + sum = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + sum += x[i][j] * y[i][0]; + } + + return sum - expected; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-1.c b/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-1.c new file mode 100644 index 0000000..5a4cad5 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-1.c @@ -0,0 +1,65 @@ +/* { dg-do run } */ + +/* Test target enter data and target update to the target using map + iterators. */ + +#include <stdlib.h> + +#define DIM1 8 +#define DIM2 15 + +int mkarray (int *x[]) +{ + int expected = 0; + for (int i = 0; i < DIM1; i++) + { + x[i] = (int *) malloc (DIM2 * sizeof (int)); + for (int j = 0; j < DIM2; j++) + { + x[i][j] = rand (); + expected += x[i][j]; + } + } + + return expected; +} + +int main (void) +{ + int *x[DIM1]; + int sum; + int expected = mkarray (x); + + #pragma omp target enter data map(to: x[:DIM1]) + #pragma omp target enter data map(iterator(i=0:DIM1), to: x[i][:DIM2]) + #pragma omp target map(from: sum) + { + sum = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + sum += x[i][j]; + } + + if (sum != expected) + return 1; + + expected = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + { + x[i][j] *= rand (); + expected += x[i][j]; + } + + #pragma omp target update to(iterator(i=0:DIM1): x[i][:DIM2]) + + #pragma omp target map(from: sum) + { + sum = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + sum += x[i][j]; + } + + return sum != expected; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-2.c b/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-2.c new file mode 100644 index 0000000..93438d0 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-2.c @@ -0,0 +1,58 @@ +/* { dg-do run } */ +/* { dg-require-effective-target offload_device_nonshared_as } */ + +/* Test target enter data and target update from the target using map + iterators. */ + +#include <stdlib.h> + +#define DIM1 8 +#define DIM2 15 + +void mkarray (int *x[]) +{ + for (int i = 0; i < DIM1; i++) + { + x[i] = (int *) malloc (DIM2 * sizeof (int)); + for (int j = 0; j < DIM2; j++) + x[i][j] = 0; + } +} + +int main (void) +{ + int *x[DIM1]; + int sum, expected; + + mkarray (x); + + #pragma omp target enter data map(alloc: x[:DIM1]) + #pragma omp target enter data map(iterator(i=0:DIM1), to: x[i][:DIM2]) + #pragma omp target map(from: expected) + { + expected = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + { + x[i][j] = (i + 1) * (j + 2); + expected += x[i][j]; + } + } + + /* Host copy of x should remain unchanged. */ + sum = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + sum += x[i][j]; + if (sum != 0) + return 1; + + #pragma omp target update from(iterator(i=0:DIM1): x[i][:DIM2]) + + /* Host copy should now be updated. */ + sum = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + sum += x[i][j]; + return sum - expected; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-3.c b/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-3.c new file mode 100644 index 0000000..a70b21c --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/target-update-iterators-3.c @@ -0,0 +1,67 @@ +/* { dg-do run } */ +/* { dg-require-effective-target offload_device_nonshared_as } */ + +/* Test target enter data and target update to the target using map + iterators with a function. */ + +#include <stdlib.h> + +#define DIM1 8 +#define DIM2 15 + +void mkarray (int *x[]) +{ + for (int i = 0; i < DIM1; i++) + { + x[i] = (int *) malloc (DIM2 * sizeof (int)); + for (int j = 0; j < DIM2; j++) + x[i][j] = rand (); + } +} + +int f (int i) +{ + return i * 2; +} + +int main (void) +{ + int *x[DIM1], x_new[DIM1][DIM2]; + int sum, expected; + + mkarray (x); + + #pragma omp target enter data map(alloc: x[:DIM1]) + #pragma omp target enter data map(iterator(i=0:DIM1), to: x[i][:DIM2]) + + /* Update x on host. */ + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + { + x_new[i][j] = x[i][j]; + x[i][j] = (i + 1) * (j + 2); + } + + /* Update a subset of x on target. */ + #pragma omp target update to(iterator(i=0:DIM1/2): x[f (i)][:DIM2]) + + #pragma omp target map(from: sum) + { + sum = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + sum += x[i][j]; + } + + /* Calculate expected value on host. */ + for (int i = 0; i < DIM1/2; i++) + for (int j = 0; j < DIM2; j++) + x_new[f (i)][j] = x[f (i)][j]; + + expected = 0; + for (int i = 0; i < DIM1; i++) + for (int j = 0; j < DIM2; j++) + expected += x_new[i][j]; + + return sum - expected; +} diff --git a/libgrust/ChangeLog b/libgrust/ChangeLog index a5641b7..71634f3 100644 --- a/libgrust/ChangeLog +++ b/libgrust/ChangeLog @@ -1,3 +1,20 @@ +2025-08-05 Marc Poulhiès <dkm@kataplop.net> + + * libproc_macro_internal/ffistring.h (FFIString__new): Likewise. + (FFIString__drop): Likewise. + * libproc_macro_internal/ident.h (Ident__new): Likewise. + (Ident__new_raw): Likewise. + (Ident__drop): Likewise. + (Ident__clone): Likewise. + * libproc_macro_internal/literal.h (Literal__from_string): Likewise. + * libproc_macro_internal/proc_macro.h (bridge_is_available): Likewise. + * libproc_macro_internal/tokenstream.h (TokenStream__new): Likewise. + (TokenStream__with_capacity): Likewise. + (TokenSream__push): Likewise. + (TokenStream__from_string): Likewise. + (TokenStream__clone): Likewise. + (TokenStream__drop): Likewise. + 2025-03-31 Arthur Cohen <arthur.cohen@embecosm.com> * libformat_parser/Makefile.am: Avoid using --config as it is unsupported by cargo 1.49. 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/ChangeLog b/libstdc++-v3/ChangeLog index 2dba9dc..09ee090 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2025-08-05 Jakub Jelinek <jakub@redhat.com> + + PR libstdc++/121373 + * src/c++23/std.cc.in (std::ranges::iter_move, std::ranges::iter_swap): + Remove exports. + 2025-08-04 Jakub Jelinek <jakub@redhat.com> hexne <printfne@gmail.com> |