diff options
52 files changed, 1479 insertions, 112 deletions
diff --git a/contrib/ChangeLog b/contrib/ChangeLog index a1db267..a4f8bb3 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,7 @@ +2025-07-08 Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> + + * prepare-commit-msg: Force default git prefixes. + 2025-07-07 Martin Jambor <mjambor@suse.cz> * filter-clang-warnings.py (skip_warning): Also ignore diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 407faa7..750fbeb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,86 @@ +2025-07-08 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp> + + * config/xtensa/xtensa.cc (xtensa_b4const_or_zero): + Remove. + (xtensa_b4const): Add a case where the value is 0, and rename + to xtensa_b4const_or_zero. + (xtensa_rtx_costs): Fix to also consider the result of + xtensa_b4constu(). + +2025-07-08 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + * config/s390/s390.md (stack_protect_get_tpsi): New insn. + (stack_protect_get_tpdi): New insn. + (stack_protect_set): Use new insn. + (stack_protect_test): Use new insn. + +2025-07-08 Robin Dapp <rdapp@ventanamicro.com> + + PR target/120461 + * config/riscv/riscv-v.cc (emit_vlmax_insn_lra): Do not emit + vsetivli for XTHeadVector. + +2025-07-08 Robin Dapp <rdapp@ventanamicro.com> + + PR target/113829 + * config/riscv/riscv-vector-builtins.cc (registered_function::overloaded_hash): + Skip non-type arguments. + +2025-07-08 Andreas Schwab <schwab@suse.de> + + PR target/120995 + * config/riscv/sync.md (zacas_atomic_cas_value_strong<mode>): + Allow op3 to be zero. + +2025-07-08 Richard Biener <rguenther@suse.de> + + * config/i386/x86-tune.def (X86_TUNE_AVX512_MASKED_EPILOGUES): + New tunable, default on for m_ZNVER4 and m_ZNVER5. + * config/i386/i386.cc (ix86_vector_costs::finish_cost): With + X86_TUNE_AVX512_MASKED_EPILOGUES and when the main loop + had a vectorization factor > 2 use a masked epilogue when + possible and when not obviously problematic. + +2025-07-08 Richard Biener <rguenther@suse.de> + + * tree-vectorizer.h (vector_costs::suggested_epilogue_mode): + Add masked output parameter and return m_masked_epilogue. + (vector_costs::m_masked_epilogue): New tristate flag. + (vector_costs::vector_costs): Initialize m_masked_epilogue. + * tree-vect-loop.cc (vect_analyze_loop_1): Pass in masked + flag to optionally initialize can_use_partial_vectors_p. + (vect_analyze_loop): For epilogues also get whether to use + a masked epilogue for this loop from the target and use + that for the first epilogue mode we try. + +2025-07-08 Richard Biener <rguenther@suse.de> + + PR tree-optimization/120358 + * tree-ssa-structalias.cc (get_constraint_for_1): Adjust + pruning of sub-variables according to the imprecise + known start offset. + +2025-07-08 Alexandre Oliva <oliva@adacore.com> + + * config/vxworks-dummy.h (TARGET_VXWORKS_VAROFF): New. + (TARGET_VXWORKS_GOTTPIC): New. + * config/vxworks.h (TARGET_VXWORKS_VAROFF): Override. + (TARGET_VXWORKS_GOTTPIC): Likewise. + * config/i386/i386.cc (output_set_got): Disable VxWorks6 GOT + sequence on VxWorks7. + (legitimize_pic_address): Accept relative addressing of + labels on VxWorks7. + (ix86_delegitimize_address_1): Likewise. + (ix86_output_addr_diff_elt): Likewise. + * config/i386/i386.md (tablejump): Likewise. + (set_got, set_got_labelled): Set no-red-zone flag on VxWorks7. + * config/i386/predicates.md (gotoff_operand): Test + TARGET_VXWORKS_VAROFF. + +2025-07-08 Alexandre Oliva <oliva@adacore.com> + + * config.gcc (vxworks-dummy.h): Add to aarch64-*-* as well. + 2025-07-07 Qing Zhao <qing.zhao@oracle.com> Revert: diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 7475f8c..fc3b547 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20250708 +20250709 diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc index a970eb8..e27bcc7 100644 --- a/gcc/auto-profile.cc +++ b/gcc/auto-profile.cc @@ -622,9 +622,11 @@ get_original_name (const char *name, bool alloc = true) } /* Suffixes of clones that compiler generates after auto-profile. */ const char *suffixes[] = {"isra", "constprop", "lto_priv", "part", "cold"}; - for (unsigned i = 0; i < sizeof (suffixes); ++i) + for (unsigned i = 0; i < sizeof (suffixes) / sizeof (const char *); ++i) { - if (strncmp (next_dot + 1, suffixes[i], strlen (suffixes[i])) == 0) + int len = strlen (suffixes[i]); + if (len == last_dot - next_dot - 1 + && strncmp (next_dot + 1, suffixes[i], strlen (suffixes[i])) == 0) { *next_dot = 0; return get_original_name (ret, false); @@ -3304,10 +3306,22 @@ cmp (const void *a, const void *b) return 0; } +/* To scalle a connected component of graph we collect desired scales of + basic blocks on the boundary and then compute a robust average. */ + +struct scale +{ + /* Scale descired. */ + sreal scale; + /* Weight for averaging computed from execution count of the edge + scale originates from. */ + uint64_t weight; +}; + /* Add scale ORIG/ANNOTATED to SCALES. */ static void -add_scale (vec <sreal> *scales, profile_count annotated, profile_count orig) +add_scale (vec <scale> *scales, profile_count annotated, profile_count orig) { if (dump_file) { @@ -3316,15 +3330,15 @@ add_scale (vec <sreal> *scales, profile_count annotated, profile_count orig) annotated.dump (dump_file); fprintf (dump_file, "\n"); } - if (orig.nonzero_p ()) + if (orig.force_nonzero () == orig) { sreal scale = annotated.guessed_local () .to_sreal_scale (orig); if (dump_file) - fprintf (dump_file, " adding scale %.16f\n", - scale.to_double ()); - scales->safe_push (scale); + fprintf (dump_file, " adding scale %.16f, weight %" PRId64 "\n", + scale.to_double (), annotated.value () + 1); + scales->safe_push ({scale, annotated.value () + 1}); } } @@ -3370,7 +3384,7 @@ afdo_adjust_guessed_profile (bb_set *annotated_bb) /* Basic blocks of connected component currently processed. */ auto_vec <basic_block, 20> bbs (n_basic_blocks_for_fn (cfun)); /* Scale factors found. */ - auto_vec <sreal, 20> scales; + auto_vec <scale, 20> scales; auto_vec <basic_block, 20> stack (n_basic_blocks_for_fn (cfun)); basic_block seed_bb; @@ -3382,9 +3396,15 @@ afdo_adjust_guessed_profile (bb_set *annotated_bb) >=2 is an id of the component BB belongs to. */ auto_vec <unsigned int, 20> component; component.safe_grow (last_basic_block_for_fn (cfun)); + profile_count max_count_in_fn = profile_count::zero (); FOR_ALL_BB_FN (seed_bb, cfun) - component[seed_bb->index] - = is_bb_annotated (seed_bb, *annotated_bb) ? 1 : 0; + if (is_bb_annotated (seed_bb, *annotated_bb)) + { + component[seed_bb->index] = 1; + max_count_in_fn = max_count_in_fn.max (seed_bb->count); + } + else + component[seed_bb->index] = 0; FOR_ALL_BB_FN (seed_bb, cfun) if (!component[seed_bb->index]) { @@ -3507,12 +3527,15 @@ afdo_adjust_guessed_profile (bb_set *annotated_bb) profile_count annotated_count = e->dest->count; profile_count out_count = profile_count::zero (); bool ok = true; + for (edge e2: e->dest->preds) if (AFDO_EINFO (e2)->is_annotated ()) annotated_count -= AFDO_EINFO (e2)->get_count (); - else if (component[e->src->index] == component_id) - out_count += e->count (); - else if (e->probability.nonzero_p ()) + else if (component[e2->src->index] == component_id) + out_count += e2->count (); + else if (is_bb_annotated (e2->src, *annotated_bb)) + annotated_count -= e2->count (); + else if (e2->probability.nonzero_p ()) { ok = false; break; @@ -3559,7 +3582,43 @@ afdo_adjust_guessed_profile (bb_set *annotated_bb) } gcc_checking_assert (scales.length ()); scales.qsort (cmp); - scale_bbs (bbs, scales[scales.length () / 2]); + + uint64_t overall_weight = 0; + for (scale &e : scales) + overall_weight += e.weight; + + uint64_t cummulated = 0, weight_sum = 0; + sreal scale_sum = 0; + for (scale &e : scales) + { + uint64_t prev = cummulated; + cummulated += e.weight; + if (cummulated >= overall_weight / 4 + && prev <= 3 * overall_weight / 4) + { + scale_sum += e.scale * e.weight; + weight_sum += e.weight; + if (dump_file) + fprintf (dump_file, " accounting scale %.16f, weight %" PRId64 "\n", + e.scale.to_double (), e.weight); + } + else if (dump_file) + fprintf (dump_file, " ignoring scale %.16f, weight %" PRId64 "\n", + e.scale.to_double (), e.weight); + } + sreal scale = scale_sum / (sreal)weight_sum; + + /* Avoid scaled regions to have very large counts. + Otherwise they may dominate ipa-profile's histogram computing cutoff + of hot basic blocks. */ + if (max_count * scale > max_count_in_fn.guessed_local ()) + { + fprintf (dump_file, "Scaling by %.16f produces max count ", scale.to_double ()); + (max_count * scale).dump (dump_file); + fprintf (dump_file, " that exceeds max count in fn; capping\n"); + scale = max_count_in_fn.guessed_local ().to_sreal_scale (max_count); + } + scale_bbs (bbs, scale); } } diff --git a/gcc/config.gcc b/gcc/config.gcc index 5953ace..8ed1113 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1847,11 +1847,11 @@ moxie-*-moxiebox*) ;; h8300-*-elf*) tmake_file="h8300/t-h8300" - tm_file="h8300/h8300.h elfos.h newlib-stdint.h h8300/elf.h" + tm_file="elfos.h h8300/h8300.h newlib-stdint.h h8300/elf.h" ;; h8300-*-linux*) tmake_file="${tmake_file} h8300/t-h8300 h8300/t-linux" - tm_file="h8300/h8300.h elfos.h gnu-user.h linux.h glibc-stdint.h h8300/linux.h" + tm_file="elfos.h h8300/h8300.h gnu-user.h linux.h glibc-stdint.h h8300/linux.h" ;; hppa*64*-*-linux*) target_cpu_default="MASK_PA_11|MASK_PA_20" diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h index cba50de..105385f 100644 --- a/gcc/config/arm/arm_neon.h +++ b/gcc/config/arm/arm_neon.h @@ -20938,11 +20938,6 @@ vbfdotq_lane_f32 (float32x4_t __r, bfloat16x8_t __a, bfloat16x4_t __b, return __builtin_neon_vbfdot_lanev4bfv4sf (__r, __a, __b, __index); } -#pragma GCC pop_options - -#pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+bf16") - typedef struct bfloat16x4x2_t { bfloat16x4_t val[2]; diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index 6b2dd65..8018b63 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -610,6 +610,12 @@ struct cum_arg #define DATA_SECTION_ASM_OP "\t.section .data" #define BSS_SECTION_ASM_OP "\t.section .bss" +/* Override default definitions from elfos.h. */ +#undef INIT_SECTION_ASM_OP +#define INIT_SECTION_ASM_OP "\t.section\t.init,\"ax\"" +#undef FINI_SECTION_ASM_OP +#define FINI_SECTION_ASM_OP "\t.section\t.fini,\"ax\"" + #undef DO_GLOBAL_CTORS_BODY #define DO_GLOBAL_CTORS_BODY \ { \ @@ -647,19 +653,11 @@ struct cum_arg /* Globalizing directive for a label. */ #define GLOBAL_ASM_OP "\t.global " +/* Override default definition from elfos.h. */ +#undef ASM_DECLARE_FUNCTION_NAME #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ ASM_OUTPUT_FUNCTION_LABEL (FILE, NAME, DECL) -/* This is how to store into the string LABEL - the symbol_ref name of an internal numbered label where - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. - - N.B.: The h8300.md branch_true and branch_false patterns also know - how to generate internal labels. */ -#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ - sprintf (LABEL, "*.%s%lu", PREFIX, (unsigned long)(NUM)) - /* This is how to output an insn to push a register on the stack. It need not be very fast code. */ @@ -690,9 +688,6 @@ struct cum_arg if ((LOG) != 0) \ fprintf (FILE, "\t.align %d\n", (LOG)) -#define ASM_OUTPUT_SKIP(FILE, SIZE) \ - fprintf (FILE, "\t.space %d\n", (int)(SIZE)) - /* This says how to output an assembler line to define a global common symbol. */ diff --git a/gcc/config/riscv/riscv-avlprop.cc b/gcc/config/riscv/riscv-avlprop.cc index bb4aceb..3031c29 100644 --- a/gcc/config/riscv/riscv-avlprop.cc +++ b/gcc/config/riscv/riscv-avlprop.cc @@ -508,7 +508,7 @@ pass_avlprop::execute (function *fn) simplify_replace_vlmax_avl (rinsn, prop.second); } - if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL) + if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL && !TARGET_XTHEADVECTOR) { /* Simplify VLMAX AVL into immediate AVL. E.g. Simplify this following case: diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 38a2d68..9fe49db 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,37 @@ +2025-07-08 Marek Polacek <polacek@redhat.com> + Andrew Pinski <quic_apinski@quicinc.com> + + PR c++/83469 + PR c++/93809 + * cp-tree.h (UNION_TYPE_P): Define. + (TYPENAME_IS_UNION_P): Define. + * decl.cc (struct typename_info): Add union_p field. + (struct typename_hasher::equal): Compare union_p field. + (build_typename_type): Use ti.union_p for union_type. Set + TYPENAME_IS_UNION_P. + * error.cc (dump_type) <case TYPENAME_TYPE>: Handle + TYPENAME_IS_UNION_P. + * module.cc (trees_out::type_node): Likewise. + * parser.cc (cp_parser_check_class_key): Allow typename key for union + types and allow union keyword for typename types. + * pt.cc (tsubst) <case TYPENAME_TYPE>: Don't conflate unions with + class_type. For TYPENAME_IS_CLASS_P, check NON_UNION_CLASS_TYPE_P + rather than CLASS_TYPE_P. Add TYPENAME_IS_UNION_P handling. + +2025-07-08 Jakub Jelinek <jakub@redhat.com> + + PR c++/117784 + * decl.cc: Implement part of C++26 P2686R4 - constexpr structured + bindings. + (cp_finish_decl): Pedwarn for C++23 and older on constinit on + structured bindings except for static/thread_local where it uses + earlier error. + (grokdeclarator): Pedwarn on constexpr structured bindings for + C++23 and older instead of emitting error always, don't clear + constexpr_p in that case. + * parser.cc (cp_parser_decomposition_declaration): Copy over + DECL_DECLARED_CONSTEXPR_P and DECL_DECLARED_CONSTINIT_P flags. + 2025-07-07 Alfie Richards <alfie.richards@arm.com> PR c++/119498 diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc index e7635fb..67ec92a 100644 --- a/gcc/ext-dce.cc +++ b/gcc/ext-dce.cc @@ -757,7 +757,7 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj, and process the inner object. */ if (paradoxical_subreg_p (y)) y = XEXP (y, 0); - else if (SUBREG_P (y) && SUBREG_BYTE (y).is_constant ()) + else if (SUBREG_P (y) && subreg_lsb (y).is_constant (&bit)) { /* If !TRULY_NOOP_TRUNCATION_MODES_P, the mode change performed by Y would normally need to be a @@ -774,8 +774,6 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj, GET_MODE (SUBREG_REG (y)))))) break; - bit = subreg_lsb (y).to_constant (); - /* If this is a wide object (more bits than we can fit in a HOST_WIDE_INT), then just break from the SET context. That will cause the iterator to walk down diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 49eef94..168c475 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2025-07-08 Andre Vehreschild <vehre@gcc.gnu.org> + + PR fortran/120637 + * class.cc (finalize_component): Return true, when a finalizable + component was detect and do not free it. + 2025-07-07 Mikael Morin <mikael@gcc.gnu.org> * trans-intrinsic.cc (conv_intrinsic_move_alloc): Add pre and diff --git a/gcc/match.pd b/gcc/match.pd index ec2f560..67b33ee 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3716,6 +3716,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if ((TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) || ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) + || (VECTOR_TYPE_P (TREE_TYPE (@1)) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, code2)) || POINTER_TYPE_P (TREE_TYPE (@1))) && bitwise_equal_p (@1, @2))) (with @@ -3754,27 +3756,39 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (code1 == EQ_EXPR && val) @3) (if (code1 == EQ_EXPR && !val) { constant_boolean_node (false, type); }) (if (code1 == NE_EXPR && !val && allbits) @4) - (if (code1 == NE_EXPR + (if ((code1 == NE_EXPR && code2 == GE_EXPR && cmp == 0 && allbits) + && ((VECTOR_BOOLEAN_TYPE_P (type) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, GT_EXPR)) + || !VECTOR_TYPE_P (TREE_TYPE (@1)))) (gt @c0 (convert @1))) - (if (code1 == NE_EXPR + (if ((code1 == NE_EXPR && code2 == LE_EXPR && cmp == 0 && allbits) + && ((VECTOR_BOOLEAN_TYPE_P (type) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, LT_EXPR)) + || !VECTOR_TYPE_P (TREE_TYPE (@1)))) (lt @c0 (convert @1))) /* (a != (b+1)) & (a > b) -> a > (b+1) */ - (if (code1 == NE_EXPR + (if ((code1 == NE_EXPR && code2 == GT_EXPR && one_after && allbits) + && ((VECTOR_BOOLEAN_TYPE_P (type) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, GT_EXPR)) + || !VECTOR_TYPE_P (TREE_TYPE (@1)))) (gt @c0 (convert @1))) /* (a != (b-1)) & (a < b) -> a < (b-1) */ - (if (code1 == NE_EXPR + (if ((code1 == NE_EXPR && code2 == LT_EXPR && one_before && allbits) + && ((VECTOR_BOOLEAN_TYPE_P (type) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, LT_EXPR)) + || !VECTOR_TYPE_P (TREE_TYPE (@1)))) (lt @c0 (convert @1))) ) ) @@ -3793,6 +3807,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if ((TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) || ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) + || (VECTOR_TYPE_P (TREE_TYPE (@1)) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, code2)) || POINTER_TYPE_P (TREE_TYPE (@1))) && operand_equal_p (@1, @2))) (with @@ -3843,6 +3859,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if ((TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) || ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) + || (VECTOR_TYPE_P (TREE_TYPE (@1))) || POINTER_TYPE_P (TREE_TYPE (@1))) && bitwise_equal_p (@1, @2))) (with @@ -3884,24 +3901,36 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (code1 == EQ_EXPR && code2 == GT_EXPR && cmp == 0 - && allbits) + && allbits + && ((VECTOR_BOOLEAN_TYPE_P (type) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, GE_EXPR)) + || !VECTOR_TYPE_P (TREE_TYPE (@1)))) (ge @c0 @2)) (if (code1 == EQ_EXPR && code2 == LT_EXPR && cmp == 0 - && allbits) + && allbits + && ((VECTOR_BOOLEAN_TYPE_P (type) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, LE_EXPR)) + || !VECTOR_TYPE_P (TREE_TYPE (@1)))) (le @c0 @2)) /* (a == (b-1)) | (a >= b) -> a >= (b-1) */ (if (code1 == EQ_EXPR && code2 == GE_EXPR && one_before - && allbits) + && allbits + && ((VECTOR_BOOLEAN_TYPE_P (type) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, GE_EXPR)) + || !VECTOR_TYPE_P (TREE_TYPE (@1)))) (ge @c0 (convert @1))) /* (a == (b+1)) | (a <= b) -> a <= (b-1) */ (if (code1 == EQ_EXPR && code2 == LE_EXPR && one_after - && allbits) + && allbits + && ((VECTOR_BOOLEAN_TYPE_P (type) + && expand_vec_cmp_expr_p (TREE_TYPE (@1), type, LE_EXPR)) + || !VECTOR_TYPE_P (TREE_TYPE (@1)))) (le @c0 (convert @1))) ) ) @@ -3966,7 +3995,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) rcmp (ne le gt ne lt ge) (simplify (op:c (cmp1:c @0 @1) (cmp2 @0 @1)) - (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + || POINTER_TYPE_P (TREE_TYPE (@0)) + || (VECTOR_TYPE_P (TREE_TYPE (@1)) + && expand_vec_cmp_expr_p (TREE_TYPE (@0), type, rcmp))) (rcmp @0 @1))))) /* Optimize (a CMP b) == (a CMP b) */ @@ -3975,7 +4007,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) rcmp (eq gt le eq ge lt) (simplify (eq:c (cmp1:c @0 @1) (cmp2 @0 @1)) - (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) + || POINTER_TYPE_P (TREE_TYPE (@0)) + || (VECTOR_TYPE_P (TREE_TYPE (@0)) + && expand_vec_cmp_expr_p (TREE_TYPE (@0), type, rcmp))) (rcmp @0 @1)))) /* (type)([0,1]@a != 0) -> (type)a @@ -5981,6 +6016,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && !expand_vec_cond_expr_p (TREE_TYPE (@1), TREE_TYPE (@0))))) (vec_cond @0 (op! @1 @3) (op! @2 @4)))) +/* (@0 ? @2 : @3) lop (@1 ? @2 : @3) --> (@0 lop @1) ? @2 : @3. */ +(for lop (bit_and bit_ior bit_xor) + (simplify + (lop + (vec_cond @0 integer_minus_onep@2 integer_zerop@3) + (vec_cond @1 @2 @3)) + (if (target_supports_op_p (TREE_TYPE (@0), lop, optab_vector)) + (vec_cond (lop @0 @1) @2 @3)))) + /* (c ? a : b) op d --> c ? (a op d) : (b op d) */ (simplify (op (vec_cond:s @0 @1 @2) @3) @@ -11635,4 +11679,4 @@ and, && VECTOR_TYPE_P (type) && direct_internal_fn_supported_p (IFN_AVG_CEIL, type, OPTIMIZE_FOR_BOTH)) (IFN_AVG_CEIL @0 @2))) -#endif +#endif
\ No newline at end of file diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3923bb7..5b38013 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,124 @@ +2025-07-08 Marek Polacek <polacek@redhat.com> + Andrew Pinski <quic_apinski@quicinc.com> + + PR c++/83469 + PR c++/93809 + * g++.dg/template/error45.C: Adjust dg-error. + * g++.dg/warn/Wredundant-tags-3.C: Remove xfail. + * g++.dg/parse/union1.C: New test. + * g++.dg/parse/union2.C: New test. + * g++.dg/parse/union3.C: New test. + * g++.dg/parse/union4.C: New test. + * g++.dg/parse/union5.C: New test. + * g++.dg/parse/union6.C: New test. + +2025-07-08 Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp> + + * gcc.target/xtensa/BGEUI-BLTUI-32k-64k.c: New. + +2025-07-08 Jakub Jelinek <jakub@redhat.com> + + PR c++/117784 + * g++.dg/cpp1z/decomp3.C (test): For constexpr structured binding + initialize from constexpr var instead of non-constexpr and expect + just a pedwarn for C++23 and older instead of error always. + * g++.dg/cpp26/decomp9.C (foo): Likewise. + * g++.dg/cpp26/decomp22.C: New test. + * g++.dg/cpp26/decomp23.C: New test. + * g++.dg/cpp26/decomp24.C: New test. + * g++.dg/cpp26/decomp25.C: New test. + +2025-07-08 Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + * gcc.target/s390/stack-protector-guard-tls-1.c: New test. + +2025-07-08 Richard Biener <rguenther@suse.de> + + * gcc.dg/guality/guality.h (guality_main): Declare noipa. + (guality_check): Likewise. + +2025-07-08 Robin Dapp <rdapp@ventanamicro.com> + + PR target/120461 + * gcc.target/riscv/rvv/xtheadvector/pr120461.c: New test. + +2025-07-08 Robin Dapp <rdapp@ventanamicro.com> + + PR target/113829 + * gcc.target/riscv/rvv/base/pr113829.c: New test. + +2025-07-08 Andreas Schwab <schwab@suse.de> + + PR target/120995 + * gcc.target/riscv/amo/zabha-zacas-atomic-cas.c: New test. + +2025-07-08 Jason Merrill <jason@redhat.com> + + * g++.dg/cpp1y/lambda-generic-variadic.C: Change to 'compile'. + +2025-07-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * gcc.target/i386/memcpy-pr120683-1.c (dg-options): Add + -fasynchronous-unwind-tables -fdwarf2-cfi-asm. + * gcc.target/i386/memcpy-pr120683-2.c: Likewise. + * gcc.target/i386/memcpy-pr120683-3.c: Likewise. + * gcc.target/i386/memcpy-pr120683-4.c: Likewise. + * gcc.target/i386/memcpy-pr120683-5.c: Likewise. + * gcc.target/i386/memcpy-pr120683-6.c: Likewise. + * gcc.target/i386/memcpy-pr120683-7.c: Likewise. + * gcc.target/i386/memcpy-strategy-12.c: Likewise. + * gcc.target/i386/memset-pr120683-1.c: Likewise. + * gcc.target/i386/memset-pr120683-10.c: Likewise. + * gcc.target/i386/memset-pr120683-11.c: Likewise. + * gcc.target/i386/memset-pr120683-12.c: Likewise. + * gcc.target/i386/memset-pr120683-13.c: Likewise. + * gcc.target/i386/memset-pr120683-14.c: Likewise. + * gcc.target/i386/memset-pr120683-15.c: Likewise. + * gcc.target/i386/memset-pr120683-16.c: Likewise. + * gcc.target/i386/memset-pr120683-17.c: Likewise. + * gcc.target/i386/memset-pr120683-18.c: Likewise. + * gcc.target/i386/memset-pr120683-19.c: Likewise. + * gcc.target/i386/memset-pr120683-2.c: Likewise. + * gcc.target/i386/memset-pr120683-20.c: Likewise. + * gcc.target/i386/memset-pr120683-21.c: Likewise. + * gcc.target/i386/memset-pr120683-22.c: Likewise. + * gcc.target/i386/memset-pr120683-23.c: Likewise. + * gcc.target/i386/memset-pr120683-3.c: Likewise. + * gcc.target/i386/memset-pr120683-4.c: Likewise. + * gcc.target/i386/memset-pr120683-5.c: Likewise. + * gcc.target/i386/memset-pr120683-6.c: Likewise. + * gcc.target/i386/memset-pr120683-7.c: Likewise. + * gcc.target/i386/memset-pr120683-8.c: Likewise. + * gcc.target/i386/memset-pr120683-9.c: Likewise. + +2025-07-08 Juergen Christ <jchrist@linux.ibm.com> + + * gcc.target/s390/vector/pattern-avg-1.c: Split test. + * gcc.target/s390/vector/pattern-mulh-1.c: Split test. + * gcc.target/s390/vector/pattern-avg-2.c: New test. + * gcc.target/s390/vector/pattern-mulh-2.c: New test. + +2025-07-08 Richard Biener <rguenther@suse.de> + + * gcc.target/i386/vect-mask-epilogue-1.c: New testcase. + * gcc.target/i386/vect-mask-epilogue-2.c: Likewise. + * gcc.target/i386/vect-epilogues-3.c: Adjust. + +2025-07-08 Andre Vehreschild <vehre@gcc.gnu.org> + + PR fortran/120637 + * gfortran.dg/asan/finalize_1.f90: New test. + +2025-07-08 Jeff Law <jlaw@ventanamicro.com> + + * gcc.dg/torture/pr120654.c: Use __builtin variants of malloc and free. + +2025-07-08 Jeff Law <jlaw@ventanamicro.com> + + * gcc.target/riscv/amo/zalrsc-rvwmo-amo-add-int.c: Adjust expected + output. + * gcc.target/riscv/amo/zalrsc-ztso-amo-add-int.c: Likewise. + 2025-07-07 Qing Zhao <qing.zhao@oracle.com> Revert: diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-pr120780.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-pr120780.c index 0d6593e..12e6c29 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-pr120780.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-pr120780.c @@ -207,7 +207,7 @@ test5 (size_t sz) } int -main (size_t sz) +main (void) { test1 (sizeof (struct container)); test1 (sizeof (struct container) - sizeof (int)); diff --git a/gcc/testsuite/gcc.dg/vect/pr101145.c b/gcc/testsuite/gcc.dg/vect/pr101145.c index cd11c03..c055ae6 100644 --- a/gcc/testsuite/gcc.dg/vect/pr101145.c +++ b/gcc/testsuite/gcc.dg/vect/pr101145.c @@ -2,7 +2,7 @@ /* { dg-additional-options "-O3" } */ #include <limits.h> -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { while (n < ++l) @@ -10,7 +10,7 @@ foo (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) { while (UINT_MAX - 64 < ++l) @@ -18,7 +18,7 @@ foo_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { l = UINT_MAX - 32; @@ -27,7 +27,7 @@ foo_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_3 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { while (n <= ++l) @@ -35,7 +35,7 @@ foo_3 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_4 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { // infininate while (0 <= ++l) @@ -43,7 +43,7 @@ foo_4 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) foo_5 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { //no loop @@ -53,7 +53,7 @@ foo_5 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) bar (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { while (--l < n) @@ -61,7 +61,7 @@ bar (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) bar_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) { while (--l < 64) @@ -69,7 +69,7 @@ bar_1 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned) return l; } -unsigned __attribute__ ((noinline)) +unsigned __attribute__ ((noipa)) bar_2 (int *__restrict__ a, int *__restrict__ b, unsigned l, unsigned n) { l = 32; diff --git a/gcc/testsuite/gcc.dg/vect/pr120922.c b/gcc/testsuite/gcc.dg/vect/pr120922.c new file mode 100644 index 0000000..1a7247a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr120922.c @@ -0,0 +1,18 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-additional-options "-fsigned-char -fno-strict-aliasing -fwrapv" } */ +/* { dg-additional-options "-march=rv64gcv_zvl1024b -mrvv-vector-bits=zvl -mrvv-max-lmul=m8 -O3" { target { riscv_v } } } */ + +char g; +unsigned char h; +int i[9][6]; +int main() { + int k[5]; + if (g) + goto l; + for (; h <= 5; h++) + i[0][h] = *k; +l: + return 0; +} + +/* { dg-final { scan-tree-dump "loop vectorized" "vect" { target riscv_v } } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/pr118348_1.c b/gcc/testsuite/gcc.target/aarch64/pr118348_1.c index 75f6dad..2715dcb 100644 --- a/gcc/testsuite/gcc.target/aarch64/pr118348_1.c +++ b/gcc/testsuite/gcc.target/aarch64/pr118348_1.c @@ -1,4 +1,4 @@ -/* { dg-do run { target aarch64_sve128_hw } } */ +/* { dg-do run { target { aarch64_sve128_hw && fstack_protector } } } */ /* { dg-options "-O2 -fopenmp-simd -fno-trapping-math -msve-vector-bits=128 --param aarch64-autovec-preference=sve-only -fstack-protector-strong" } */ #pragma GCC target "+sve" diff --git a/gcc/testsuite/gcc.target/aarch64/pr118348_2.c b/gcc/testsuite/gcc.target/aarch64/pr118348_2.c index 2e20004..4ce8d20 100644 --- a/gcc/testsuite/gcc.target/aarch64/pr118348_2.c +++ b/gcc/testsuite/gcc.target/aarch64/pr118348_2.c @@ -1,4 +1,4 @@ -/* { dg-do run { target aarch64_sve256_hw } } */ +/* { dg-do run { target { aarch64_sve256_hw && fstack_protector } } } */ /* { dg-options "-O2 -fopenmp-simd -fno-trapping-math -msve-vector-bits=256 --param aarch64-autovec-preference=sve-only -fstack-protector-strong" } */ #include "pr118348_1.c" diff --git a/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c b/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c new file mode 100644 index 0000000..a1a601d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-fdump-tree-original-all" } */ + +typedef int v4i __attribute__((vector_size(4*sizeof(int)))); + +/* Ensure we can simplify `VEC_COND_EXPR(a OP1 b) OP2 VEC_COND_EXPR(a OP3 b)` + * into `VEC_COND_EXPR(a OP4 b)` + */ + +void use (v4i const *z); + +void +g (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x > *y | *x == *y; // expect >= + *t = *x > *y | *x <= *y; // expect true +} + +void +h (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x <= *y & *x >= *y; // expect x == y + *t = *x <= *y & *x != *y; // expect x<y +} + +void +i (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x == *y | *x != *y; // expect true + *t = *x == *y & *x != *y; // expect false +} + +void +k (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x < *y | *x == *y; // x <= y + *t = *x < *y & *x > *y; // expect false +} + +void +m (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x <= *y ^ *x >= *y; /* expect x != y */ + *t = *x <= *y ^ *x != *y; /* expect x <= y */ +} + +void +n (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x == *y ^ *x != *y; /* expect true */ + *t = *x == *y ^ *x == *y; /* expect false */ +} + + +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*>=\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*==\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*<\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*<=\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*!=\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*>=\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*;" "original" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120642.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120642.c new file mode 100644 index 0000000..1a72580 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr120642.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-O -mcpu=xt-c920 -mrvv-vector-bits=zvl" } */ +int __attribute__((__vector_size__(4 * sizeof(int)))) v; +void foo() { v /= 3; } diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h index 3de89f4..7e2c93e 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h @@ -4,7 +4,9 @@ #include <stdint-gcc.h> #include <stdbool.h> -typedef __uint128_t uint128_t; +#if __riscv_xlen == 64 +typedef unsigned __int128 uint128_t; +#endif /******************************************************************************/ /* Saturation Add (unsigned and signed) */ diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u128.c index 395a4cb..79f6297 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u128.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u16-from-u128.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u128.c index 3c8b728..e5a9462 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u128.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u32-from-u128.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u64-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u64-from-u128.c index e5572de..cbe2a22 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u64-from-u128.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u64-from-u128.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u128.c index 2e9c39a..1f54c30 100644 --- a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u128.c +++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-1-u8-from-u128.c @@ -1,4 +1,4 @@ -/* { dg-do run { target { riscv_v } } } */ +/* { dg-do run { target { rv64 } } } */ /* { dg-additional-options "-std=c99" } */ #include "sat_arith.h" diff --git a/gcc/testsuite/gcc.target/s390/vector/pattern-avg-1.c b/gcc/testsuite/gcc.target/s390/vector/pattern-avg-1.c index 30c6ed4..285ebc9 100644 --- a/gcc/testsuite/gcc.target/s390/vector/pattern-avg-1.c +++ b/gcc/testsuite/gcc.target/s390/vector/pattern-avg-1.c @@ -22,4 +22,5 @@ TEST(char,short,16) TEST(short,int,8) TEST(int,long,4) -/* { dg-final { scan-tree-dump-times "\.AVG_CEIL" 6 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.AVG_CEIL" 6 "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump-times "\.AVG_CEIL" 4 "optimized" { target { ! lp64 } } } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-1.c b/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-1.c index f71ef06..f0b37d6 100644 --- a/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-1.c +++ b/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-1.c @@ -23,6 +23,5 @@ TEST(char,short,16,8) TEST(short,int,8,16) -TEST(int,long,4,32) -/* { dg-final { scan-tree-dump-times "\.MULH" 6 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.MULH" 4 "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-2.c b/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-2.c index 6ac6855..2ff66b7 100644 --- a/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-2.c +++ b/gcc/testsuite/gcc.target/s390/vector/pattern-mulh-2.c @@ -21,6 +21,7 @@ (((unsigned T2)l[i] * (unsigned T2)r[i]) >> S); \ } +TEST(int,long,4,32) TEST(long,__int128,2,64) -/* { dg-final { scan-tree-dump-times "\.MULH" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\.MULH" 4 "optimized" } } */ diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc index 7e0ac69..e8fe035 100644 --- a/gcc/tree-inline.cc +++ b/gcc/tree-inline.cc @@ -2888,11 +2888,9 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, profile_count count) profile_count::adjust_for_ipa_scaling (&num, &den); ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = - ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (count, - ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count); + ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (num, den); EXIT_BLOCK_PTR_FOR_FN (cfun)->count = - EXIT_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (count, - ENTRY_BLOCK_PTR_FOR_FN (src_cfun)->count); + EXIT_BLOCK_PTR_FOR_FN (src_cfun)->count.apply_scale (num, den); if (src_cfun->eh) init_eh_for_function (); diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index 4696943..2d01a4b 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -2859,7 +2859,19 @@ vect_gen_vector_loop_niters (loop_vec_info loop_vinfo, tree niters, we have to represent the vector niter TYPE_MAX_VALUE + 1 / vf. */ if (stmts != NULL && const_vf > 0) { - if (niters_no_overflow) + if (niters_no_overflow + && LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)) + { + int_range<1> vr (type, + wi::one (TYPE_PRECISION (type)), + wi::div_ceil (wi::max_value + (TYPE_PRECISION (type), + TYPE_SIGN (type)), + const_vf, + TYPE_SIGN (type))); + set_range_info (niters_vector, vr); + } + else if (niters_no_overflow) { int_range<1> vr (type, wi::one (TYPE_PRECISION (type)), diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc index d5044d5..42e0015 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -7822,7 +7822,7 @@ vectorizable_reduction (loop_vec_info loop_vinfo, inside the loop body. The last operand is the reduction variable, which is defined by the loop-header-phi. */ - tree vectype_out = STMT_VINFO_VECTYPE (stmt_info); + tree vectype_out = SLP_TREE_VECTYPE (slp_for_stmt_info); STMT_VINFO_REDUC_VECTYPE (reduc_info) = vectype_out; STMT_VINFO_REDUC_VECTYPE_IN (reduc_info) = vectype_in; diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 5767a35..da20127 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -13368,6 +13368,14 @@ vect_analyze_stmt (vec_info *vinfo, gcc_unreachable (); } + if (PURE_SLP_STMT (stmt_info) && !node) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "handled only by SLP analysis\n"); + return opt_result::success (); + } + tree saved_vectype = STMT_VINFO_VECTYPE (stmt_info); if (node) STMT_VINFO_VECTYPE (stmt_info) = SLP_TREE_VECTYPE (node); @@ -13381,14 +13389,6 @@ vect_analyze_stmt (vec_info *vinfo, *need_to_vectorize = true; } - if (PURE_SLP_STMT (stmt_info) && !node) - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "handled only by SLP analysis\n"); - return opt_result::success (); - } - /* When we arrive here with a non-SLP statement and we are supposed to use SLP for everything fail vectorization. */ if (!node) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4298304..090c5ce 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,175 @@ +2025-07-08 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/118681 + * testsuite/20_util/unsynchronized_pool_resource/118681.cc: Fix + deallocate argument. + +2025-07-08 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/118681 + * src/c++17/memory_resource.cc (choose_block_size): New + function. + (synchronized_pool_resource::do_allocate): Use choose_block_size + to determine appropriate block size. + (synchronized_pool_resource::do_deallocate): Likewise + (unsynchronized_pool_resource::do_allocate): Likewise. + (unsynchronized_pool_resource::do_deallocate): Likewise + * testsuite/20_util/synchronized_pool_resource/118681.cc: New + test. + * testsuite/20_util/unsynchronized_pool_resource/118681.cc: New + test. + +2025-07-08 Jonathan Wakely <jwakely@redhat.com> + + * include/debug/forward_list (_Safe_forward_list<>::_M_swap): + Adapt to _M_this() signature change. + +2025-07-08 Tomasz Kamiński <tkaminsk@redhat.com> + + PR libstdc++/119861 + * include/std/format (formatter<_Rg, _CharT>::set_separator) + (formatter<_Rg, _CharT>::set_brackets): Constrain with + (format_kind<_Rg> == range_format::sequence). + * testsuite/std/format/ranges/pr119861_neg.cc: New test. + +2025-07-08 Luc Grosheintz <luc.grosheintz@gmail.com> + + PR libstdc++/120914 + * include/std/span (span): Update CTAD to enable + integral constants [P3029R1]. + * include/std/mdspan (extents): ditto. + (mdspan): ditto. + * testsuite/23_containers/span/deduction.cc: Test deduction + guide. + * testsuite/23_containers/mdspan/extents/misc.cc: ditto. + * testsuite/23_containers/mdspan/mdspan.cc: ditto. + +2025-07-08 Luc Grosheintz <luc.grosheintz@gmail.com> + + * testsuite/23_containers/span/contiguous_range_neg.cc: Silence + warning about unused variable myspan. + +2025-07-08 Luc Grosheintz <luc.grosheintz@gmail.com> + + PR libstdc++/107761 + * include/bits/version.def (mdspan): Set to 202207 and remove + no_stdname. + * include/bits/version.h: Regenerate. + * testsuite/23_containers/mdspan/version.cc: Test presence + of feature test macro. + +2025-07-08 Luc Grosheintz <luc.grosheintz@gmail.com> + + PR libstdc++/107761 + * include/std/mdspan (mdspan): New class. + * src/c++23/std.cc.in (mdspan): Add. + * testsuite/23_containers/mdspan/class_mandate_neg.cc: New test. + * testsuite/23_containers/mdspan/mdspan.cc: New test. + * testsuite/23_containers/mdspan/layout_like.h: Add class + LayoutLike which models a user-defined layout. + * testsuite/23_containers/mdspan/out_of_bounds_neg.cc: New file. + +2025-07-08 Luc Grosheintz <luc.grosheintz@gmail.com> + + * include/std/mdspan (__mdspan::__size): New function. + +2025-07-08 Luc Grosheintz <luc.grosheintz@gmail.com> + + * testsuite/23_containers/mdspan/extents/custom_integer.cc: + Delete IntLike and include "int_like.h". + * testsuite/23_containers/mdspan/extents/int_like.h: Add + IntLike. + +2025-07-08 Luc Grosheintz <luc.grosheintz@gmail.com> + + * include/std/mdspan (extents): Check prerequisite of the ctor that + static_extent(i) == dynamic_extent || extent(i) == other.extent(i). + * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc: + Test the implemented prerequisite. + * testsuite/23_containers/mdspan/extents/extents_mismatch_neg.cc: New file. + +2025-07-08 Luc Grosheintz <luc.grosheintz@gmail.com> + + * include/std/mdspan: Check prerequisites of + layout_*::operator() with _GLIBCXX_DEBUG_ASSERTs. + * testsuite/23_containers/mdspan/layouts/debug/out_of_bounds_neg.cc: + Add tests for prerequisites. + +2025-07-08 Tomasz Kamiński <tkaminsk@redhat.com> + + * include/std/queue (formatter<queue<_Tp, _Container>, _CharT>) + (formatter<priority_queue<_Tp, _Container, _Compare>, _CharT>): + Add _GLIBCXX_RESOLVE_LIB_DEFECTS comments. + +2025-07-08 François Dumont <frs.dumont@gmail.com> + + PR c++/116369 + * config/abi/pre/gnu-versioned-namespace.ver: Use new const qualified symbols. + * config/abi/pre/gnu.ver: Add new const qualified symbols. + * include/debug/safe_base.h + (_Safe_iterator_base::_M_sequence): Declare as pointer-to-const. + (_Safe_iterator_base::_M_attach, _M_attach_single): New, take pointer-to-const + _Safe_sequence_base. + (_Safe_sequence_base::_M_detach_all, _M_detach_singular, _M_revalidate_singular) + (_M_swap, _M_get_mutex): New, const qualified. + (_Safe_sequence_base::_M_attach, _M_attach_single, _M_detach, _M_detach_single): + const qualify. + * include/debug/safe_container.h (_Safe_container<>::_M_cont): Add const qualifier. + (_Safe_container<>::_M_swap_base): New. + (_Safe_container(_Safe_container&&, const _Alloc&, std::false_type)): + Adapt to use latter. + (_Safe_container<>::operator=(_Safe_container&&)): Likewise. + (_Safe_container<>::_M_swap): Likewise and take parameter as const reference. + * include/debug/safe_unordered_base.h + (_Safe_local_iterator_base::_M_safe_container): New. + (_Safe_local_iterator_base::_Safe_local_iterator_base): Take + _Safe_unordered_container_base as pointer-to-const. + (_Safe_unordered_container_base::_M_attach, _M_attach_single): New, take + container as _Safe_unordered_container_base pointer-to-const. + (_Safe_unordered_container_base::_M_local_iterators, _M_const_local_iterators): + Add mutable. + (_Safe_unordered_container_base::_M_detach_all, _M_swap): New, const qualify. + (_Safe_unordered_container_base::_M_attach_local, _M_attach_local_single) + (_M_detach_local, _M_detach_local_single): Add const qualifier. + * include/debug/safe_unordered_container.h (_Safe_unordered_container::_M_self()): New. + * include/debug/safe_unordered_container.tcc + (_Safe_unordered_container::_M_invalidate_if, _M_invalidated_local_if): Use latter. + * include/debug/safe_iterator.h (_Safe_iterator<>::_M_attach, _M_attach_single): + Take _Safe_sequence_base as pointer-to-const. + (_Safe_iterator<>::_M_get_sequence): Add const_cast and comment about it. + * include/debug/safe_local_iterator.h (_Safe_local_iterator<>): Replace usages + of _M_sequence member by _M_safe_container(). + (_Safe_local_iterator<>::_M_attach, _M_attach_single): Take + _Safe_unordered_container_base as pointer-to-const. + (_Safe_local_iterator<>::_M_get_sequence): Rename into... + (_Safe_local_iterator<>::_M_get_ucontainer): ...this. Add necessary const_cast and + comment to explain it. + (_Safe_local_iterator<>::_M_is_begin, _M_is_end): Adapt. + * include/debug/safe_local_iterator.tcc: Adapt. + * include/debug/safe_sequence.h + (_Safe_sequence<>::_M_invalidate_if, _M_transfer_from_if): Add const qualifier. + * include/debug/safe_sequence.tcc: Adapt. + * include/debug/deque (std::__debug::deque::erase): Adapt to use new const + qualified methods. + * include/debug/formatter.h: Adapt. + * include/debug/forward_list (_Safe_forward_list::_M_this): Add const + qualification and return pointer for consistency with 'this' keyword. + (_Safe_forward_list::_M_swap_aux): Rename into... + (_Safe_forward_list::_S_swap_aux): ...this and take sequence as const reference. + (forward_list<>::resize): Adapt to use const methods. + * include/debug/list (list<>::resize): Likewise. + * src/c++11/debug.cc: Adapt to const qualification. + * testsuite/util/testsuite_containers.h + (forward_members_unordered::forward_members_unordered): Add check on local_iterator + conversion to const_local_iterator. + (forward_members::forward_members): Add check on iterator conversion to + const_iterator. + * testsuite/23_containers/unordered_map/const_container.cc: New test case. + * testsuite/23_containers/unordered_multimap/const_container.cc: New test case. + * testsuite/23_containers/unordered_multiset/const_container.cc: New test case. + * testsuite/23_containers/unordered_set/const_container.cc: New test case. + * testsuite/23_containers/vector/debug/mutex_association.cc: Adapt. + 2025-07-07 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/120949 diff --git a/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt b/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt index ac11d5d..5d55287 100644 --- a/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt +++ b/libstdc++-v3/config/abi/post/x86_64-linux-gnu/x32/baseline_symbols.txt @@ -2124,6 +2124,10 @@ FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policy FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2EOS5_@@GLIBCXX_3.4.28 FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27 FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS5_@@GLIBCXX_3.4.26 +FUNC:_ZNSt12__sso_stringC1Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringC2Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringD1Ev@@GLIBCXX_3.4.34 +FUNC:_ZNSt12__sso_stringD2Ev@@GLIBCXX_3.4.34 FUNC:_ZNSt12bad_weak_ptrD0Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt12bad_weak_ptrD1Ev@@GLIBCXX_3.4.15 FUNC:_ZNSt12bad_weak_ptrD2Ev@@GLIBCXX_3.4.15 @@ -3221,6 +3225,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcRKS FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcOS3_@@GLIBCXX_3.4.23 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcRKS3_@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructEjc@@GLIBCXX_3.4.21 +FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructILb0EEEvPKcj@@GLIBCXX_3.4.34 +FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructILb1EEEvPKcj@@GLIBCXX_3.4.34 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKcS4_EEEEvT_SB_St20forward_iterator_tag@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21 @@ -3374,6 +3380,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC1EPwRKS FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwOS3_@@GLIBCXX_3.4.23 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_Alloc_hiderC2EPwRKS3_@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructEjw@@GLIBCXX_3.4.21 +FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructILb0EEEvPKwj@@GLIBCXX_3.4.34 +FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructILb1EEEvPKwj@@GLIBCXX_3.4.34 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPKwS4_EEEEvT_SB_St20forward_iterator_tag@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21 FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPKwEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21 @@ -3941,6 +3949,8 @@ FUNC:_ZNSt8__detail15_List_node_base11_M_transferEPS0_S1_@@GLIBCXX_3.4.15 FUNC:_ZNSt8__detail15_List_node_base4swapERS0_S1_@@GLIBCXX_3.4.15 FUNC:_ZNSt8__detail15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.15 FUNC:_ZNSt8__detail15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.15 +FUNC:_ZNSt8__format25__locale_encoding_to_utf8ERKSt6localeSt17basic_string_viewIcSt11char_traitsIcEEPv@@GLIBCXX_3.4.34 +FUNC:_ZNSt8__format26__with_encoding_conversionERKSt6locale@@GLIBCXX_3.4.34 FUNC:_ZNSt8bad_castD0Ev@@GLIBCXX_3.4 FUNC:_ZNSt8bad_castD1Ev@@GLIBCXX_3.4 FUNC:_ZNSt8bad_castD2Ev@@GLIBCXX_3.4 @@ -4617,6 +4627,7 @@ OBJECT:0:GLIBCXX_3.4.30 OBJECT:0:GLIBCXX_3.4.31 OBJECT:0:GLIBCXX_3.4.32 OBJECT:0:GLIBCXX_3.4.33 +OBJECT:0:GLIBCXX_3.4.34 OBJECT:0:GLIBCXX_3.4.4 OBJECT:0:GLIBCXX_3.4.5 OBJECT:0:GLIBCXX_3.4.6 diff --git a/libstdc++-v3/include/bits/max_size_type.h b/libstdc++-v3/include/bits/max_size_type.h index 73a6d14..30c5b12 100644 --- a/libstdc++-v3/include/bits/max_size_type.h +++ b/libstdc++-v3/include/bits/max_size_type.h @@ -38,6 +38,7 @@ #include <ext/numeric_traits.h> #include <bit> // __bit_width #include <numbers> +#include <limits> // __glibcxx_integral_traps // This header implements unsigned and signed integer-class types (as per // [iterator.concept.winc]) that are one bit wider than the widest supported @@ -775,10 +776,27 @@ namespace ranges static constexpr bool is_signed = false; static constexpr bool is_integer = true; static constexpr bool is_exact = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = true; + static constexpr bool traps = __glibcxx_integral_traps; + static constexpr int radix = 2; static constexpr int digits = __gnu_cxx::__int_traits<_Sp::__rep>::__digits + 1; static constexpr int digits10 = static_cast<int>(digits * numbers::ln2 / numbers::ln10); + static constexpr int max_digits10 = 0; + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool is_iec559 = false; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm_loss = false; + static constexpr bool tinyness_before = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr float_round_style round_style = round_toward_zero; static constexpr _Sp min() noexcept @@ -791,6 +809,30 @@ namespace ranges static constexpr _Sp lowest() noexcept { return min(); } + + static constexpr _Sp + denorm_min() noexcept + { return 0; } + + static constexpr _Sp + epsilon() noexcept + { return 0; } + + static constexpr _Sp + round_error() noexcept + { return 0; } + + static constexpr _Sp + infinity() noexcept + { return 0; } + + static constexpr _Sp + quiet_NaN() noexcept + { return 0; } + + static constexpr _Sp + signaling_NaN() noexcept + { return 0; } }; template<> @@ -802,9 +844,26 @@ namespace ranges static constexpr bool is_signed = true; static constexpr bool is_integer = true; static constexpr bool is_exact = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr bool traps = __glibcxx_integral_traps; + static constexpr int radix = 2; static constexpr int digits = numeric_limits<_Sp>::digits - 1; static constexpr int digits10 = static_cast<int>(digits * numbers::ln2 / numbers::ln10); + static constexpr int max_digits10 = 0; + static constexpr int min_exponent = 0; + static constexpr int min_exponent10 = 0; + static constexpr int max_exponent = 0; + static constexpr int max_exponent10 = 0; + static constexpr bool is_iec559 = false; + static constexpr bool has_infinity = false; + static constexpr bool has_quiet_NaN = false; + static constexpr bool has_signaling_NaN = false; + static constexpr bool has_denorm_loss = false; + static constexpr bool tinyness_before = false; + static constexpr float_denorm_style has_denorm = denorm_absent; + static constexpr float_round_style round_style = round_toward_zero; static constexpr _Dp min() noexcept @@ -817,6 +876,30 @@ namespace ranges static constexpr _Dp lowest() noexcept { return min(); } + + static constexpr _Dp + denorm_min() noexcept + { return 0; } + + static constexpr _Dp + epsilon() noexcept + { return 0; } + + static constexpr _Dp + round_error() noexcept + { return 0; } + + static constexpr _Dp + infinity() noexcept + { return 0; } + + static constexpr _Dp + quiet_NaN() noexcept + { return 0; } + + static constexpr _Dp + signaling_NaN() noexcept + { return 0; } }; template<> diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h index a196a0f..f2b4601 100644 --- a/libstdc++-v3/include/bits/shared_ptr.h +++ b/libstdc++-v3/include/bits/shared_ptr.h @@ -909,6 +909,64 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> { }; +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + + /** + * @brief Provides ownership-based hashing. + * @headerfile memory + * @since C++26 + */ + struct owner_hash + { + template<typename _Tp> + size_t + operator()(const shared_ptr<_Tp>& __s) const noexcept + { return __s.owner_hash(); } + + template<typename _Tp> + size_t + operator()(const weak_ptr<_Tp>& __s) const noexcept + { return __s.owner_hash(); } + + using is_transparent = void; + }; + + /** + * @brief Provides ownership-based mixed equality comparisons of + * shared and weak pointers. + * @headerfile memory + * @since C++26 + */ + struct owner_equal + { + template<typename _Tp1, typename _Tp2> + bool + operator()(const shared_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept + { return __lhs.owner_equal(__rhs); } + + template<typename _Tp1, typename _Tp2> + bool + operator()(const shared_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept + { return __lhs.owner_equal(__rhs); } + + template<typename _Tp1, typename _Tp2> + bool + operator()(const weak_ptr<_Tp1>& __lhs, + const shared_ptr<_Tp2>& __rhs) const noexcept + { return __lhs.owner_equal(__rhs); } + + template<typename _Tp1, typename _Tp2> + bool + operator()(const weak_ptr<_Tp1>& __lhs, + const weak_ptr<_Tp2>& __rhs) const noexcept + { return __lhs.owner_equal(__rhs); } + + using is_transparent = void; + }; +#endif + /** * @brief Base class allowing use of the member function `shared_from_this`. * @headerfile memory diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index b4be1b4..fb868e7 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1122,6 +1122,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_less(const __weak_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t + _M_owner_hash() const noexcept + { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); } +#endif + // Friend function injected into enclosing namespace and found by ADL friend inline bool operator==(const __shared_count& __a, const __shared_count& __b) noexcept @@ -1225,6 +1231,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_less(const __shared_count<_Lp>& __rhs) const noexcept { return std::less<_Sp_counted_base<_Lp>*>()(this->_M_pi, __rhs._M_pi); } +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t + _M_owner_hash() const noexcept + { return std::hash<_Sp_counted_base<_Lp>*>()(this->_M_pi); } +#endif + // Friend function injected into enclosing namespace and found by ADL friend inline bool operator==(const __weak_count& __a, const __weak_count& __b) noexcept @@ -1715,6 +1727,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_refcount._M_less(__rhs._M_refcount); } /// @} +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t owner_hash() const noexcept { return _M_refcount._M_owner_hash(); } + + template<typename _Tp1> + bool + owner_equal(__shared_ptr<_Tp1, _Lp> const& __rhs) const noexcept + { return _M_refcount == __rhs._M_refcount; } + + template<typename _Tp1> + bool + owner_equal(__weak_ptr<_Tp1, _Lp> const& __rhs) const noexcept + { return _M_refcount == __rhs._M_refcount; } +#endif + protected: // This constructor is non-standard, it is used by allocate_shared. template<typename _Alloc, typename... _Args> @@ -2098,6 +2124,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION owner_before(const __weak_ptr<_Tp1, _Lp>& __rhs) const noexcept { return _M_refcount._M_less(__rhs._M_refcount); } +#ifdef __glibcxx_smart_ptr_owner_equality // >= C++26 + size_t owner_hash() const noexcept { return _M_refcount._M_owner_hash(); } + + template<typename _Tp1> + bool + owner_equal(const __shared_ptr<_Tp1, _Lp> & __rhs) const noexcept + { return _M_refcount == __rhs._M_refcount; } + + template<typename _Tp1> + bool + owner_equal(const __weak_ptr<_Tp1, _Lp> & __rhs) const noexcept + { return _M_refcount == __rhs._M_refcount; } +#endif + void reset() noexcept { __weak_ptr().swap(*this); } diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index f1015ab..31385b5 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -2007,6 +2007,15 @@ ftms = { }; ftms = { + name = smart_ptr_owner_equality; + values = { + v = 202306; + cxxmin = 26; + hosted = yes; + }; +}; + +ftms = { name = sstream_from_string_view; values = { v = 202306; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 80f6586..aa53f29 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -2249,6 +2249,16 @@ #endif /* !defined(__cpp_lib_polymorphic) && defined(__glibcxx_want_polymorphic) */ #undef __glibcxx_want_polymorphic +#if !defined(__cpp_lib_smart_ptr_owner_equality) +# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED +# define __glibcxx_smart_ptr_owner_equality 202306L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_smart_ptr_owner_equality) +# define __cpp_lib_smart_ptr_owner_equality 202306L +# endif +# endif +#endif /* !defined(__cpp_lib_smart_ptr_owner_equality) && defined(__glibcxx_want_smart_ptr_owner_equality) */ +#undef __glibcxx_want_smart_ptr_owner_equality + #if !defined(__cpp_lib_sstream_from_string_view) # if (__cplusplus > 202302L) && _GLIBCXX_HOSTED # define __glibcxx_sstream_from_string_view 202306L diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory index 1da03b3..763a57e 100644 --- a/libstdc++-v3/include/std/memory +++ b/libstdc++-v3/include/std/memory @@ -121,6 +121,7 @@ #define __glibcxx_want_smart_ptr_for_overwrite #define __glibcxx_want_to_address #define __glibcxx_want_transparent_operators +#define __glibcxx_want_smart_ptr_owner_equality #include <bits/version.h> #if __cplusplus >= 201103L && __cplusplus <= 202002L && _GLIBCXX_HOSTED diff --git a/libstdc++-v3/src/c++17/memory_resource.cc b/libstdc++-v3/src/c++17/memory_resource.cc index fddfe2c..c61569f 100644 --- a/libstdc++-v3/src/c++17/memory_resource.cc +++ b/libstdc++-v3/src/c++17/memory_resource.cc @@ -182,8 +182,8 @@ namespace pmr // versions will not use this symbol. monotonic_buffer_resource::~monotonic_buffer_resource() { release(); } - namespace { - +namespace +{ // aligned_size<N> stores the size and alignment of a memory allocation. // The size must be a multiple of N, leaving the low log2(N) bits free // to store the base-2 logarithm of the alignment. @@ -221,7 +221,7 @@ namespace pmr return (n + alignment - 1) & ~(alignment - 1); } - } // namespace +} // namespace // Memory allocated by the upstream resource is managed in a linked list // of _Chunk objects. A _Chunk object recording the size and alignment of @@ -307,8 +307,8 @@ namespace pmr // Helper types for synchronized_pool_resource & unsynchronized_pool_resource - namespace { - +namespace +{ // Simple bitset with runtime size. // Tracks which blocks in a pool chunk are used/unused. struct bitset @@ -636,7 +636,7 @@ namespace pmr static_assert(sizeof(big_block) == (2 * sizeof(void*))); - } // namespace +} // namespace // A pool that serves blocks of a particular size. // Each pool manages a number of chunks. @@ -868,7 +868,16 @@ namespace pmr using big_block::big_block; }; - namespace { +namespace +{ + // N.B. it is important that we don't skip any power of two sizes if there + // is a non-power of two size between them, e.g. must not have pool sizes + // of 24 and 40 without having a pool size of 32. Otherwise an allocation + // of 32 bytes with alignment 16 would choose the 40-byte pool which is not + // correctly aligned for 16-byte alignment. It would be OK (but suboptimal) + // to have no pool of size 32 if we have pool sizes of 16 and 64 and no + // non-power of two sizes between those, because the example of (32, 16) + // would choose the 64-byte pool, which would be correctly aligned. constexpr size_t pool_sizes[] = { 8, 16, 24, @@ -983,7 +992,7 @@ namespace pmr using exclusive_lock = lock_guard<shared_mutex>; #endif - } // namespace +} // namespace __pool_resource:: __pool_resource(const pool_options& opts, memory_resource* upstream) @@ -1075,12 +1084,33 @@ namespace pmr return p; } + // Determine the appropriate allocation size, rounding up to a multiple + // of the alignment if needed. + static inline size_t + choose_block_size(size_t bytes, size_t alignment) + { + if (bytes == 0) [[unlikely]] + return alignment; + + // Use bit_ceil in case alignment is invalid (i.e. not a power of two). + size_t mask = std::__bit_ceil(alignment) - 1; + // Round up to a multiple of alignment. + size_t block_size = (bytes + mask) & ~mask; + + if (block_size >= bytes) [[likely]] + return block_size; + + // Wrapped around to zero, bytes must have been impossibly large. + return numeric_limits<size_t>::max(); + } + + #ifdef _GLIBCXX_HAS_GTHREADS // synchronized_pool_resource members. /* Notes on implementation and thread safety: * - * Each synchronized_pool_resource manages an linked list of N+1 _TPools + * Each synchronized_pool_resource manages a linked list of N+1 _TPools * objects, where N is the number of threads using the pool resource. * Each _TPools object has its own set of pools, with their own chunks. * The first element of the list, _M_tpools[0], can be used by any thread. @@ -1242,24 +1272,6 @@ namespace pmr return pools; } - static inline size_t - choose_block_size(size_t bytes, size_t alignment) - { - if (bytes == 0) [[unlikely]] - return alignment; - - // Use bit_ceil in case alignment is invalid (i.e. not a power of two). - size_t mask = std::__bit_ceil(alignment) - 1; - // Round up to a multiple of alignment. - size_t block_size = (bytes + mask) & ~mask; - - if (block_size >= bytes) [[likely]] - return block_size; - - // Wrapped around to zero, bytes must have been impossibly large. - return numeric_limits<size_t>::max(); - } - // Override for memory_resource::do_allocate void* synchronized_pool_resource:: diff --git a/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc b/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc new file mode 100644 index 0000000..311ddf2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_equal/cmp.cc @@ -0,0 +1,105 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.6 Struct owner_equal [util.smartptr.owner.equal] + +#include <memory> +#include <algorithm> +#include <testsuite_hooks.h> + +struct A { }; + +struct B { A a[2]; }; + +int +test01() +{ + // test empty shared_ptr owners compare equivalent + std::owner_equal eq; + std::shared_ptr<A> p1; + std::shared_ptr<A> p2; + VERIFY( eq(p1, p2) && eq(p2, p1) ); + std::weak_ptr<A> p3; + VERIFY( eq(p1, p3) && eq(p3, p1) ); + VERIFY( eq(p1, p3) && eq(p3, p1) ); + return 0; +} + + +// Construction from pointer +int +test02() +{ + std::owner_equal eq; + + std::shared_ptr<A> empty; + + std::shared_ptr<A> a1(new A); + VERIFY( !eq(empty, a1) && !eq(a1, empty) ); + + std::shared_ptr<A> a2(new A); + VERIFY( !eq(a1, a2) && !eq(a2, a1) ); + + std::weak_ptr<A> w1(a1); + VERIFY( eq(a1, w1) && eq(w1, a1) ); + + std::weak_ptr<A> w2(a2); + VERIFY( !eq(w1, w2) && !eq(w2, w1) ); + + a1.reset(); + VERIFY( eq(empty, a1) && eq(a1, empty) ); + VERIFY( !eq(a1, w1) && !eq(w1, a1) ); + + a2.reset(); + VERIFY( eq(a2, a1) && eq(a1, a2) ); + + return 0; +} + +// aliasing +int +test03() +{ + std::owner_equal eq; + + std::shared_ptr<B> b(new B); + std::shared_ptr<A> a0(b, &b->a[0]); + std::shared_ptr<A> a1(b, &b->a[1]); + // values are different but owners are equivalent: + VERIFY( a0 < a1 && eq(a0, a1) && eq(b, a0) && eq(b, a1) ); + + std::weak_ptr<A> w0(a0); + std::weak_ptr<A> w1(a1); + VERIFY( eq(w0, w1) && eq(w1, w0) ); + VERIFY( eq(a0, w1) && eq(w1, a0) ); + VERIFY( eq(w0, a1) && eq(a1, w0) ); + + return 0; +} + +// as binary predicate +int +test04() +{ + std::owner_equal eq; + + std::shared_ptr<B> b(new B); + std::shared_ptr<A> a0(b, &b->a[0]); + std::shared_ptr<A> a1(b, &b->a[1]); + std::shared_ptr<A> c(new A); + std::weak_ptr<A> a[3]{a0, a1, c}; + std::weak_ptr<A>* p = std::unique(a, a+3, eq); + VERIFY( p == &a[2] ); + + return 0; +} + +int +main() +{ + test01(); + test02(); + test03(); + test04(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/owner_equal/noexcept.cc b/libstdc++-v3/testsuite/20_util/owner_equal/noexcept.cc new file mode 100644 index 0000000..fb479f6 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_equal/noexcept.cc @@ -0,0 +1,30 @@ +// { dg-do compile { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.6 Struct owner_equal [util.smartptr.owner.equal] + +#include <memory> + +#ifndef __cpp_lib_smart_ptr_owner_equality +# error "Feature-test macro for smart ptr owner equality missing in <memory>" +#elif __cpp_lib_smart_ptr_owner_equality != 202306L +# error "Feature-test macro for smart ptr owner equality has wrong value in <memory>" +#endif + +const std::owner_equal eq; +const std::shared_ptr<int> si; +const std::weak_ptr<int> wi; +static_assert( noexcept(!eq(si, si)) ); +static_assert( noexcept(!eq(si, wi)) ); +static_assert( noexcept(!eq(wi, si)) ); +static_assert( noexcept(!eq(wi, wi)) ); +static_assert( noexcept(!eq(si, wi)) ); +static_assert( noexcept(!eq(wi, si)) ); +const std::shared_ptr<long> sl; +const std::weak_ptr<char> wc; +static_assert( noexcept(!eq(si, si)) ); +static_assert( noexcept(!eq(si, sl)) ); +static_assert( noexcept(!eq(sl, si)) ); +static_assert( noexcept(!eq(si, wc)) ); +static_assert( noexcept(!eq(wc, si)) ); +static_assert( noexcept(!eq(wc, wi)) ); diff --git a/libstdc++-v3/testsuite/20_util/owner_equal/version.cc b/libstdc++-v3/testsuite/20_util/owner_equal/version.cc new file mode 100644 index 0000000..db29154 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_equal/version.cc @@ -0,0 +1,13 @@ +// { dg-do compile { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 17.3.2 Header <version> synopsis [version.syn] + +#include <version> + +#ifndef __cpp_lib_smart_ptr_owner_equality +# error "Feature-test macro for smart ptr owner equality missing in <version>" +#elif __cpp_lib_smart_ptr_owner_equality != 202306L +# error "Feature-test macro for smart ptr owner equality has wrong value in <version>" +#endif + diff --git a/libstdc++-v3/testsuite/20_util/owner_hash/cmp.cc b/libstdc++-v3/testsuite/20_util/owner_hash/cmp.cc new file mode 100644 index 0000000..c03a926 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_hash/cmp.cc @@ -0,0 +1,87 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.5 Struct owner_hash [util.smartptr.owner.hash] + +#include <memory> +#include <algorithm> +#include <testsuite_hooks.h> + +struct A { }; + +struct B { A a[2]; }; + +int +test01() +{ + // test empty shared_ptr hashes compare equivalent + std::owner_hash oh; + std::shared_ptr<A> p1; + std::shared_ptr<A> p2; + VERIFY( oh(p1) == oh(p2) ); + std::weak_ptr<A> p3; + VERIFY( oh(p1) == oh(p3) ); + VERIFY( oh(p1) == oh(p3) ); + return 0; +} + + +// Construction from pointer +int +test02() +{ + std::owner_hash oh; + + std::shared_ptr<A> empty; + + std::shared_ptr<A> a1(new A); + VERIFY( oh(empty) != oh(a1) ); + + std::shared_ptr<A> a2(new A); + VERIFY( oh(a1) != oh(a2) ); + + std::weak_ptr<A> w1(a1); + VERIFY( oh(a1) == oh(w1) ); + + std::weak_ptr<A> w2(a2); + VERIFY( oh(w1) != oh(w2) ); + + a1.reset(); + VERIFY( oh(empty) == oh(a1) ); + VERIFY( oh(a1) != oh(w1) ); + + a2.reset(); + VERIFY( oh(a2) == oh(a1) ); + + return 0; +} + +// aliasing +int +test03() +{ + std::owner_hash oh; + + std::shared_ptr<B> b(new B); + std::shared_ptr<A> a0(b, &b->a[0]); + std::shared_ptr<A> a1(b, &b->a[1]); + // values are different but owners are ohuivalent: + VERIFY( a0 < a1 && oh(a0) == oh(a1) && oh(b) == oh(a0) && oh(b) == oh(a1) ); + + std::weak_ptr<A> w0(a0); + std::weak_ptr<A> w1(a1); + VERIFY( oh(w0) == oh(w1) ); + VERIFY( oh(a0) == oh(w1) ); + VERIFY( oh(w0) == oh(a1) ); + + return 0; +} + +int +main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/owner_hash/noexcept.cc b/libstdc++-v3/testsuite/20_util/owner_hash/noexcept.cc new file mode 100644 index 0000000..12b2f2f --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/owner_hash/noexcept.cc @@ -0,0 +1,16 @@ +// { dg-do compile { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.5 Struct owner_hash [util.smartptr.owner.hash] + +#include <memory> + +const std::owner_hash oh; +const std::shared_ptr<int> si; +const std::weak_ptr<int> wi; +static_assert( noexcept(!oh(si)) ); +static_assert( noexcept(!oh(wi)) ); +const std::shared_ptr<long> sl; +const std::weak_ptr<char> wc; +static_assert( noexcept(!oh(sl)) ); +static_assert( noexcept(!oh(wc)) ); diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_equal.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_equal.cc new file mode 100644 index 0000000..7ec8691 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_equal.cc @@ -0,0 +1,74 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.2.6 shared_ptr observers [util.smartptr.shared.obs] + +#include <memory> +#include <testsuite_hooks.h> + +struct A +{ + int i; + virtual ~A() { } +}; + +struct B : A +{ +}; + +void +test01() +{ + // test empty shared_ptr owners compare equivalent + std::shared_ptr<A> p1; + std::shared_ptr<B> p2; + VERIFY( p1.owner_equal(p2) && p2.owner_equal(p1) ); +} + + +// Construction from pointer +void +test02() +{ + std::shared_ptr<A> a0; + + std::shared_ptr<A> a1(new A); + VERIFY( !a1.owner_equal(a0) && !a0.owner_equal(a1) ); + + std::shared_ptr<B> b1(new B); + VERIFY( !a1.owner_equal(b1) && !b1.owner_equal(a1) ); + + std::shared_ptr<A> a2(a1); + VERIFY( a1.owner_equal(a2) && a2.owner_equal(a1) ); + a2 = b1; + VERIFY( b1.owner_equal(a2) && a2.owner_equal(b1) ); + + std::weak_ptr<A> w1(a1); + VERIFY( a1.owner_equal(w1) && w1.owner_equal(a1) ); + std::weak_ptr<A> w2(a2); + VERIFY( b1.owner_equal(w2) && w2.owner_equal(b1) ); + + static_assert( noexcept(a1.owner_equal(a0)) ); + static_assert( noexcept(a1.owner_equal(b1)) ); + static_assert( noexcept(b1.owner_equal(a1)) ); + static_assert( noexcept(a1.owner_equal(w1)) ); + static_assert( noexcept(b1.owner_equal(w1)) ); +} + +// Aliasing +void +test03() +{ + std::shared_ptr<A> p1(new A()); + std::shared_ptr<int> p2(p1, &p1->i); + VERIFY( p1.owner_equal(p2) && p2.owner_equal(p1) ); +} + +int +main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_hash.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_hash.cc new file mode 100644 index 0000000..8e6c02c --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/owner_hash.cc @@ -0,0 +1,71 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.2.6 shared_ptr observers [util.smartptr.shared.obs] + +#include <memory> +#include <testsuite_hooks.h> + +struct A +{ + int i; + virtual ~A() { } +}; + +struct B : A +{ +}; + +void +test01() +{ + // test empty shared_ptr hashes compare equivalent + std::shared_ptr<A> p1; + std::shared_ptr<B> p2; + VERIFY( p1.owner_hash() == p2.owner_hash() ); +} + + +// Construction from pointer +void +test02() +{ + std::shared_ptr<A> a0; + + std::shared_ptr<A> a1(new A); + VERIFY( a1.owner_hash() != a0.owner_hash() ); + + std::shared_ptr<B> b1(new B); + VERIFY( a1.owner_hash() != b1.owner_hash() ); + + std::shared_ptr<A> a2(a1); + VERIFY( a1.owner_hash() == a2.owner_hash() ); + a2 = b1; + VERIFY( b1.owner_hash() == a2.owner_hash() ); + + std::weak_ptr<A> w1(a1); + VERIFY( a1.owner_hash() == w1.owner_hash() ); + std::weak_ptr<A> w2(a2); + VERIFY( b1.owner_hash() == w2.owner_hash() ); + + static_assert( noexcept(a1.owner_hash()) ); + static_assert( noexcept(b1.owner_hash()) ); +} + +// Aliasing +void +test03() +{ + std::shared_ptr<A> p1(new A()); + std::shared_ptr<int> p2(p1, &p1->i); + VERIFY( p1.owner_hash() == p2.owner_hash() ); +} + +int +main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/synchronized_pool_resource/118681.cc b/libstdc++-v3/testsuite/20_util/synchronized_pool_resource/118681.cc index 6d7434f..facbf00 100644 --- a/libstdc++-v3/testsuite/20_util/synchronized_pool_resource/118681.cc +++ b/libstdc++-v3/testsuite/20_util/synchronized_pool_resource/118681.cc @@ -1,4 +1,5 @@ // { dg-do run { target c++17 } } +// { dg-require-gthreads "" } // Bug 118681 - unsynchronized_pool_resource may fail to respect alignment #define RESOURCE std::pmr::synchronized_pool_resource diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_equal.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_equal.cc new file mode 100644 index 0000000..0217a6e --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_equal.cc @@ -0,0 +1,52 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.3.6 weak_ptr observers [util.smartptr.weak.obs] + +#include <memory> +#include <testsuite_hooks.h> + +struct A { }; +struct B { }; + +void +test01() +{ + // test empty weak_ptr owners compare equivalent + std::weak_ptr<A> p1; + std::weak_ptr<B> p2; + VERIFY( p1.owner_equal(p2) && p2.owner_equal(p1) ); + + std::shared_ptr<B> p3; + VERIFY( p1.owner_equal(p3) && p3.owner_equal(p1) ); + + static_assert( noexcept(p1.owner_equal(p1)) ); + static_assert( noexcept(p1.owner_equal(p2)) ); + static_assert( noexcept(p1.owner_equal(p3)) ); + static_assert( noexcept(p2.owner_equal(p1)) ); +} + + +void +test02() +{ + std::shared_ptr<A> a0; + std::weak_ptr<A> w0(a0); + + std::shared_ptr<A> a1(new A); + std::weak_ptr<A> w1(a1); + VERIFY( a1.owner_equal(w1) && w1.owner_equal(a1) ); + VERIFY( !w1.owner_equal(w0) && !w0.owner_equal(w1) ); + VERIFY( !w1.owner_equal(a0) && !a0.owner_equal(w1) ); + + std::shared_ptr<B> b1(new B); + VERIFY( !w1.owner_equal(b1) && !b1.owner_equal(w1) ); +} + +int +main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_hash.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_hash.cc new file mode 100644 index 0000000..148a93b --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/observers/owner_hash.cc @@ -0,0 +1,50 @@ +// { dg-do run { target c++26 } } +// { dg-require-effective-target hosted } + +// N5008 20.3.2.3.6 weak_ptr observers [util.smartptr.weak.obs] + +#include <memory> +#include <testsuite_hooks.h> + +struct A { }; +struct B { }; + +void +test01() +{ + // test empty weak_ptr hashes compare equivalent + std::weak_ptr<A> p1; + std::weak_ptr<B> p2; + VERIFY( p1.owner_hash() == p2.owner_hash() ); + + std::shared_ptr<B> p3; + VERIFY( p1.owner_hash() == p3.owner_hash() ); + + static_assert( noexcept(p1.owner_hash()) ); + static_assert( noexcept(p2.owner_hash()) ); +} + + +void +test02() +{ + std::shared_ptr<A> a0; + std::weak_ptr<A> w0(a0); + + std::shared_ptr<A> a1(new A); + std::weak_ptr<A> w1(a1); + VERIFY( a1.owner_hash() == w1.owner_hash() ); + VERIFY( w1.owner_hash() != w0.owner_hash() ); + VERIFY( w1.owner_hash() != a0.owner_hash() ); + + std::shared_ptr<B> b1(new B); + VERIFY( w1.owner_hash() != b1.owner_hash() ); +} + +int +main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc b/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc index 4739d9e..fbd783b 100644 --- a/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc +++ b/libstdc++-v3/testsuite/std/ranges/iota/max_size_type.cc @@ -352,6 +352,9 @@ static_assert(numeric_limits<max_size_t>::is_specialized); static_assert(!numeric_limits<max_size_t>::is_signed); static_assert(numeric_limits<max_size_t>::is_integer); static_assert(numeric_limits<max_size_t>::is_exact); +static_assert(numeric_limits<max_size_t>::is_bounded); +static_assert(numeric_limits<max_size_t>::is_modulo); +static_assert(numeric_limits<max_size_t>::radix == 2); // We can't unconditionally use numeric_limits here because __int128 is an // integral type only in GNU mode. #if __SIZEOF_INT128__ @@ -379,6 +382,9 @@ static_assert(numeric_limits<max_diff_t>::is_specialized); static_assert(numeric_limits<max_diff_t>::is_signed); static_assert(numeric_limits<max_diff_t>::is_integer); static_assert(numeric_limits<max_diff_t>::is_exact); +static_assert(numeric_limits<max_diff_t>::is_bounded); +static_assert(!numeric_limits<max_diff_t>::is_modulo); +static_assert(numeric_limits<max_diff_t>::radix == 2); static_assert(numeric_limits<max_diff_t>::digits == numeric_limits<max_size_t>::digits - 1); static_assert(numeric_limits<max_diff_t>::digits10 @@ -400,6 +406,31 @@ static_assert(max_diff_t(max_size_t(1) << (numeric_limits<max_size_t>::digits-1)) == numeric_limits<max_diff_t>::min()); +template <typename integer_class> +constexpr bool verify_numeric_limits_values_not_meaningful_for = true + && (numeric_limits<integer_class>::max_digits10 == 0) + && (numeric_limits<integer_class>::min_exponent == 0) + && (numeric_limits<integer_class>::min_exponent10 == 0) + && (numeric_limits<integer_class>::max_exponent == 0) + && (numeric_limits<integer_class>::max_exponent10 == 0) + && !numeric_limits<integer_class>::is_iec559 + && !numeric_limits<integer_class>::has_infinity + && !numeric_limits<integer_class>::has_quiet_NaN + && !numeric_limits<integer_class>::has_signaling_NaN + && !numeric_limits<integer_class>::has_denorm_loss + && !numeric_limits<integer_class>::tinyness_before + && (numeric_limits<integer_class>::has_denorm == std::denorm_absent) + && (numeric_limits<integer_class>::round_style == std::round_toward_zero) + && (numeric_limits<integer_class>::denorm_min() == 0) + && (numeric_limits<integer_class>::epsilon() == 0) + && (numeric_limits<integer_class>::round_error() == 0) + && (numeric_limits<integer_class>::infinity() == 0) + && (numeric_limits<integer_class>::quiet_NaN() == 0) + && (numeric_limits<integer_class>::signaling_NaN() == 0); + +static_assert(verify_numeric_limits_values_not_meaningful_for<max_size_t>); +static_assert(verify_numeric_limits_values_not_meaningful_for<max_diff_t>); + // Verify that the types are structural types and can therefore be used // as NTTP types. template<max_size_t V> struct Su { static_assert(V*V == V+132); }; |