diff options
202 files changed, 8372 insertions, 1188 deletions
diff --git a/contrib/gennews b/contrib/gennews index bb5ac92..6eab091 100755 --- a/contrib/gennews +++ b/contrib/gennews @@ -23,6 +23,7 @@ website=http://gcc.gnu.org/ files=" + gcc-15/index.html gcc-15/changes.html gcc-14/index.html gcc-14/changes.html gcc-13/index.html gcc-13/changes.html gcc-12/index.html gcc-12/changes.html diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c838fcd..8d412b6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,141 @@ +2025-04-24 Jakub Jelinek <jakub@redhat.com> + Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + PR target/119873 + * config/s390/s390.cc (s390_call_saved_register_used): Don't return + true if default definition of PARM_DECL SSA_NAME of the same register + is passed in call saved register. + (s390_function_ok_for_sibcall): Adjust comment. + +2025-04-24 Jan Hubicka <hubicka@ucw.cz> + + PR target/119919 + * config/i386/i386.cc (ix86_vector_costs::add_stmt_cost): Account + correctly cond_expr and min/max when one of operands is 0 or -1. + +2025-04-24 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/119924 + * ipa-cp.cc (update_counts_for_self_gen_clones): Use nonzero_p. + (update_profiling_info): Likewise. + (update_specialized_profile): Likewise. + +2025-04-24 Richard Sandiford <richard.sandiford@arm.com> + + PR target/119610 + * config/aarch64/aarch64.cc (aarch64_allocate_and_probe_stack_space): + Add a bytes_below_sp parameter and use it to calculate the CFA + offsets. Attach the first SVE CFA note to the move into the + associated temporary register. + (aarch64_allocate_and_probe_stack_space): Update calls accordingly. + Start out with bytes_per_sp set to the frame size and decrement + it after each allocation. + +2025-04-24 Kyrylo Tkachov <ktkachov@nvidia.com> + + * opts.cc (validate_ipa_reorder_locality_lto_partition): Check opts + instead of opts_set for x_flag_ipa_reorder_for_locality. + (finish_options): Update call site. + +2025-04-24 Kyrylo Tkachov <ktkachov@nvidia.com> + + * common.opt (LTO_PARTITION_DEFAULT): Delete. + (flto-partition=): Change default back to balanced. + * flag-types.h (lto_partition_model): Remove LTO_PARTITION_DEFAULT. + * opts.cc (validate_ipa_reorder_locality_lto_partition): + Check opts_set->x_flag_lto_partition instead of LTO_PARTITION_DEFAULT. + (finish_options): Remove handling of LTO_PARTITION_DEFAULT. + +2025-04-24 Jakub Jelinek <jakub@redhat.com> + + PR debug/119711 + * dwarf2out.h (struct dw_val_node): Add u member. + (struct dw_loc_descr_node): Remove dw_loc_opc, dtprel, + frame_offset_rel and dw_loc_addr members. + (dw_loc_opc, dw_loc_dtprel, dw_loc_frame_offset_rel, dw_loc_addr): + Define. + (struct dw_attr_struct): Remove dw_attr member. + (dw_attr): Define. + * dwarf2out.cc (loc_descr_equal_p_1): Use dw_loc_dtprel instead of + dtprel. + (output_loc_operands, new_addr_loc_descr, loc_checksum, + loc_checksum_ordered): Likewise. + (resolve_args_picking_1): Use dw_loc_frame_offset_rel instead of + frame_offset_rel. + (loc_list_from_tree_1): Likewise. + (resolve_addr_in_expr): Use dw_loc_dtprel instead of dtprel. + (copy_deref_exprloc): Copy val_class, val_entry and v members + instead of whole dw_loc_oprnd1 and dw_loc_oprnd2. + (optimize_string_length): Copy val_class, val_entry and v members + instead of whole dw_attr_val. + (hash_loc_operands): Use dw_loc_dtprel instead of dtprel. + (compare_loc_operands, compare_locs): Likewise. + +2025-04-24 liuhongt <hongtao.liu@intel.com> + + PR target/103750 + * config/i386/sse.md (*<avx512>_cmp<mode>3_and15): New define_insn. + (*<avx512>_ucmp<mode>3_and15): Ditto. + (*<avx512>_cmp<mode>3_and3): Ditto. + (*avx512vl_ucmpv2di3_and3): Ditto. + (*<avx512>_cmp<V48H_AVX512VL:mode>3_zero_extend<SWI248x:mode>): + Change operands[3] predicate to <cmp_imm_predicate>. + (*<avx512>_cmp<V48H_AVX512VL:mode>3_zero_extend<SWI248x:mode>_2): + Ditto. + (*<avx512>_cmp<mode>3): Add GET_MODE_NUNITS (<MODE>mode) >= 8 + to the condition. + (*<avx512>_ucmp<mode>3): Ditto. + (V48_AVX512VL_4): New mode iterator. + (VI48_AVX512VL_4): Ditto. + (V8_AVX512VL_2): Ditto. + +2025-04-23 Jan Hubicka <hubicka@ucw.cz> + + * ipa-cp.cc (base_count): Remove. + (struct caller_statistics): Rename n_hot_calls to n_interesting_calls; + add called_without_ipa_profile. + (init_caller_stats): Update. + (cs_interesting_for_ipcp_p): New function. + (gather_caller_stats): collect n_interesting_calls and + called_without_profile. + (ipcp_cloning_candidate_p): Use n_interesting-calls rather then hot. + (good_cloning_opportunity_p): Rewrite heuristics when IPA profile is + present + (estimate_local_effects): Update. + (value_topo_info::propagate_effects): Update. + (compare_edge_profile_counts): Remove. + (ipcp_propagate_stage): Do not collect base_count. + (get_info_about_necessary_edges): Record whether function is called + without profile. + (decide_about_value): Update. + (ipa_cp_cc_finalize): Do not initialie base_count. + * profile-count.cc (profile_count::operator*): New. + (profile_count::operator*=): New. + * profile-count.h (profile_count::operator*): Declare + (profile_count::operator*=): Declare. + * params.opt: Remove ipa-cp-profile-count-base. + * doc/invoke.texi: Likewise. + +2025-04-23 Jan Hubicka <hubicka@ucw.cz> + + * config/i386/i386.cc (ix86_vector_costs::add_stmt_cost): Cost truth_value + exprs. + +2025-04-23 liuhongt <hongtao.liu@intel.com> + + * config/i386/predicates.md (vector_or_0_or_1s_operand): New predicate. + (nonimm_or_0_or_1s_operand): Ditto. + * config/i386/sse.md (vcond_mask_<mode><sseintvecmodelower>): + Extend the predicate of operands1 to accept 0 or allones + operands. + (vcond_mask_<mode><sseintvecmodelower>): Ditto. + (vcond_mask_v1tiv1ti): Ditto. + (vcond_mask_<mode><sseintvecmodelower>): Ditto. + * config/i386/i386.md (mov<mode>cc): Ditto for operands[2] and + operands[3]. + * config/i386/i386-expand.cc (ix86_expand_sse_fp_minmax): + Force immediate_operand to register. + 2025-04-22 Jan Hubicka <hubicka@ucw.cz> * config/i386/i386.cc (ix86_vector_costs::add_stmt_cost): Add special cases diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 1041049..c872ff4 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20250423 +20250425 diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index d43b3ae..4016382 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -1084,9 +1084,9 @@ c_common_post_options (const char **pfilename) /* Change flag_abi_version to be the actual current ABI level, for the benefit of c_cpp_builtins, and to make comparison simpler. */ - const int latest_abi_version = 20; - /* Generate compatibility aliases for ABI v13 (8.2) by default. */ - const int abi_compat_default = 13; + const int latest_abi_version = 21; + /* Generate compatibility aliases for ABI v18 (GCC 13) by default. */ + const int abi_compat_default = 18; #define clamp(X) if (X == 0 || X > latest_abi_version) X = latest_abi_version clamp (flag_abi_version); diff --git a/gcc/cobol/ChangeLog b/gcc/cobol/ChangeLog index 27c31c1..d7d8596 100644 --- a/gcc/cobol/ChangeLog +++ b/gcc/cobol/ChangeLog @@ -1,3 +1,20 @@ +2025-04-24 Robert Dubner <rdubner@symas.com> + + * genapi.cc: (initialize_variable_internal): Change TRACE1 formatting. + (create_and_call): Repair RETURN-CODE processing. + (mh_source_is_group): Repair run-time IF type comparison. + (psa_FldLiteralA): Change TRACE1 formatting. + (parser_symbol_add): Eliminate unnecessary code. + * genutil.cc: Eliminate SET_EXCEPTION_CODE macro. + (get_data_offset_dest): Repair set_exception_code logic. + (get_data_offset_source): Likewise. + (get_binary_value): Likewise. + (refer_refmod_length): Likewise. + (refer_fill_depends): Likewise. + (refer_offset_dest): Likewise. + (refer_size_dest): Likewise. + (refer_offset_source): Likewise. + 2025-04-16 Bob Dubner <rdubner@symas.com> PR cobol/119759 diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index c8911f9..e44364a 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -1229,7 +1229,40 @@ initialize_variable_internal( cbl_refer_t refer, } else { - TRACE1_FIELD_VALUE("", parsed_var, "") + // Convert strings of spaces to "<SPACES>" + tree spaces = gg_define_int(0); + if( parsed_var->type == FldGroup + || parsed_var->type == FldAlphanumeric + || parsed_var->type == FldAlphaEdited + || parsed_var->type == FldLiteralA ) + { + gg_assign(spaces, integer_one_node); + tree counter = gg_define_int(parsed_var->data.capacity); + WHILE(counter, gt_op, integer_zero_node) + { + gg_decrement(counter); + IF( gg_indirect(member(parsed_var->var_decl_node, "data"), counter), + ne_op, + build_int_cst_type(UCHAR, ' ') ) + { + gg_assign(spaces, integer_zero_node); + } + ELSE + { + } + ENDIF + } + WEND + } + IF(spaces, eq_op, integer_one_node) + { + TRACE1_TEXT(" <SPACES>") + } + ELSE + { + TRACE1_FIELD_VALUE("", parsed_var, "") + } + ENDIF } TRACE1_END } @@ -12341,7 +12374,7 @@ create_and_call(size_t narg, // Because the CALL had a RETURNING clause, RETURN-CODE doesn't return a // value. So, we make sure it is zero - gg_assign(var_decl_return_code, build_int_cst_type(SHORT, 0)); +//// gg_assign(var_decl_return_code, build_int_cst_type(SHORT, 0)); if( returned_value_type == CHAR_P ) { @@ -12352,7 +12385,7 @@ create_and_call(size_t narg, gg_add( member(returned.field->var_decl_node, "data"), refer_offset_dest(returned))); gg_assign(returned_length, - refer_size_dest(returned)); + gg_cast(TREE_TYPE(returned_length), refer_size_dest(returned))); // The returned value is a string of nbytes, which by specification // has to be at least as long as the returned_length of the target: @@ -12442,28 +12475,9 @@ create_and_call(size_t narg, } else { - // Because no explicit returning value is expected, we switch to - // the IBM default behavior, where the returned INT value is assigned - // to our RETURN-CODE: - returned_value = gg_define_variable(SHORT); - - // Before doing the call, we save the COBOL program_state: - push_program_state(); - gg_assign(returned_value, gg_cast(SHORT, call_expr)); - // And after the call, we restore it: - pop_program_state(); - - // We know that the returned value is a 2-byte little-endian INT: - gg_assign( var_decl_return_code, - returned_value); - TRACE1 - { - TRACE1_HEADER - gg_printf("returned value: %d", - gg_cast(INT, var_decl_return_code), - NULL_TREE); - TRACE1_END - } + // Because no explicit returning value is expected, we just call it. We + // expect COBOL routines to set RETURN-CODE when they think it necessary. + gg_append_statement(call_expr); } for( size_t i=0; i<narg; i++ ) @@ -14810,7 +14824,7 @@ mh_source_is_group( cbl_refer_t &destref, tree dbytes = refer_size_dest(destref); tree sbytes = tsrc.length; - IF( sbytes, ge_op, dbytes ) + IF( sbytes, ge_op, gg_cast(TREE_TYPE(sbytes), dbytes) ) { // There are too many source bytes gg_memcpy(tdest, tsource, dbytes); @@ -16140,12 +16154,12 @@ psa_FldLiteralA(struct cbl_field_t *field ) DECL_PRESERVE_P (field->var_decl_node) = 1; nvar += 1; } - TRACE1 - { - TRACE1_INDENT - TRACE1_TEXT("Finished") - TRACE1_END - } +// TRACE1 +// { +// TRACE1_INDENT +// TRACE1_TEXT("Finished") +// TRACE1_END +// } } #endif @@ -16535,24 +16549,15 @@ parser_symbol_add(struct cbl_field_t *new_var ) size_t our_index = new_var->our_index; - // During the early stages of implementing cbl_field_t::our_index, there - // were execution paths in parse.y and parser.cc that resulted in our_index - // not being set. I hereby try to use field_index() to find the index - // of this field to resolve those. I note that field_index does a linear - // search of the symbols[] table to find that index. That's why I don't - // use it routinely; it results in O(N^squared) computational complexity - // to do a linear search of the symbol table for each symbol - if( !our_index && new_var->type != FldLiteralN && !(new_var->attr & intermediate_e)) { - our_index = field_index(new_var); - if( our_index == (size_t)-1 ) - { - // Hmm. Couldn't find it. Seems odd. - our_index = 0; - } + // During the early stages of implementing cbl_field_t::our_index, there + // were execution paths in parse.y and parser.cc that resulted in + // our_index not being set. Those should be gone. + fprintf(stderr, "our_index is NULL under unanticipated circumstances"); + gcc_assert(false); } // When we create the cblc_field_t structure, we need a data pointer @@ -16561,7 +16566,7 @@ parser_symbol_add(struct cbl_field_t *new_var ) // we calculate data as the pointer to our parent's data plus our // offset. - // declare and define the structure. This code *must* match + // Declare and define the structure. This code *must* match // the C structure declared in libgcobol.c. Towards that end, the // variables are declared in descending order of size in order to // make the packing match up. diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc index d11e464..0322833 100644 --- a/gcc/cobol/genutil.cc +++ b/gcc/cobol/genutil.cc @@ -54,8 +54,6 @@ bool skip_exception_processing = true; bool suppress_dest_depends = false; -#define SET_EXCEPTION_CODE(a) do{set_exception_code((a));}while(0); - std::vector<std::string>current_filename; tree var_decl_exception_code; // int __gg__exception_code; @@ -266,6 +264,20 @@ get_integer_value(tree value, gg_assign(value, gg_cast(TREE_TYPE(value), temp)); } +static +tree +get_any_capacity(cbl_field_t *field) + { + if( field->attr & (any_length_e | intermediate_e) ) + { + return member(field->var_decl_node, "capacity"); + } + else + { + return build_int_cst_type(LONG, field->data.capacity); + } + } + static tree get_data_offset_dest(cbl_refer_t &refer, int *pflags = NULL) @@ -324,45 +336,27 @@ get_data_offset_dest(cbl_refer_t &refer, // Pick up the integer value of the subscript: static tree subscript = gg_define_variable(LONG, "..gdod_subscript", vs_file_static); - if( process_this_exception(ec_bound_subscript_e) ) + get_integer_value(subscript, + refer.subscripts[i].field, + refer_offset_dest(refer.subscripts[i]), + CHECK_FOR_FRACTIONAL_DIGITS); + IF( var_decl_rdigits, + ne_op, + integer_zero_node ) { - get_integer_value(value64, - refer.subscripts[i].field, - refer_offset_dest(refer.subscripts[i]), - CHECK_FOR_FRACTIONAL_DIGITS); - IF( var_decl_rdigits, - ne_op, - integer_zero_node ) - { - if( enabled_exceptions.match(ec_bound_subscript_e) ) - { - // The subscript isn't an integer - SET_EXCEPTION_CODE(ec_bound_subscript_e); - gg_assign(subscript, gg_cast(TREE_TYPE(subscript), integer_zero_node)); - } - else - { - rt_error("error: a table subscript is not an integer"); - } - } - ELSE - { - gg_assign(subscript, gg_cast(TREE_TYPE(subscript), value64)); - } - ENDIF + // The subscript isn't an integer + set_exception_code(ec_bound_subscript_e); } - else + ELSE { - get_integer_value(subscript, - refer.subscripts[i].field, - refer_offset_dest(refer.subscripts[i])); } + ENDIF - // gg_printf("%s(): We have a subscript of %d from %s\n", - // gg_string_literal(__func__), - // subscript, - // gg_string_literal(refer.subscripts[i].field->name), - // NULL_TREE); +// gg_printf("%s(): We have a subscript of %d from %s\n", +// gg_string_literal(__func__), +// subscript, +// gg_string_literal(refer.subscripts[i].field->name), +// NULL_TREE); if( (refer.subscripts[i].field->attr & FIGCONST_MASK) == zero_value_e ) { @@ -381,74 +375,46 @@ get_data_offset_dest(cbl_refer_t &refer, // Make it zero-based: gg_decrement(subscript); - if( process_this_exception(ec_bound_subscript_e) ) + + IF( subscript, lt_op, gg_cast(TREE_TYPE(subscript), integer_zero_node) ) + { + // The subscript is too small + set_exception_code(ec_bound_subscript_e); + gg_assign(subscript, build_int_cst_type(TREE_TYPE(subscript), 0)); + } + ELSE { - // gg_printf("process_this_exception is true\n", NULL_TREE); - IF( subscript, lt_op, gg_cast(TREE_TYPE(subscript), integer_zero_node) ) + // gg_printf("parent->occurs.ntimes() is %d\n", build_int_cst_type(INT, parent->occurs.ntimes()), NULL_TREE); + IF( subscript, + ge_op, + build_int_cst_type(TREE_TYPE(subscript), parent->occurs.ntimes()) ) { - // The subscript is too small - SET_EXCEPTION_CODE(ec_bound_subscript_e); - gg_assign(subscript, gg_cast(TREE_TYPE(subscript), integer_zero_node)); + // The subscript is too large + set_exception_code(ec_bound_subscript_e); + gg_assign(subscript, build_int_cst_type(TREE_TYPE(subscript), 0)); } ELSE { - // gg_printf("parent->occurs.ntimes() is %d\n", build_int_cst_type(INT, parent->occurs.ntimes()), NULL_TREE); - IF( subscript, - ge_op, - build_int_cst_type(TREE_TYPE(subscript), parent->occurs.ntimes()) ) + // We have a good subscript: + // Check for an ODO violation: + if( parent->occurs.depending_on ) { - // The subscript is too large - if( enabled_exceptions.match(ec_bound_subscript_e) ) + cbl_field_t *depending_on = cbl_field_of(symbol_at(parent->occurs.depending_on)); + get_integer_value(value64, depending_on); + IF( subscript, ge_op, value64 ) { - SET_EXCEPTION_CODE(ec_bound_subscript_e); - gg_assign(subscript, gg_cast(TREE_TYPE(subscript), integer_zero_node)); - } - else - { - rt_error("error: table subscript is too large"); + gg_assign(var_decl_odo_violation, integer_one_node); } + ELSE + ENDIF } - ELSE - { - // We have a good subscript: - // Check for an ODO violation: - if( parent->occurs.depending_on ) - { - cbl_field_t *depending_on = cbl_field_of(symbol_at(parent->occurs.depending_on)); - get_integer_value(value64, depending_on); - IF( subscript, ge_op, value64 ) - { - gg_assign(var_decl_odo_violation, integer_one_node); - } - ELSE - ENDIF - } - tree augment = gg_multiply(subscript, build_int_cst_type(INT, parent->data.capacity)); - gg_assign(retval, gg_add(retval, gg_cast(SIZE_T, augment))); - } - ENDIF + tree augment = gg_multiply(subscript, get_any_capacity(parent)); + gg_assign(retval, gg_add(retval, gg_cast(SIZE_T, augment))); } ENDIF } - else - { - // Assume a good subscript: - // Check for an ODO violation: - if( parent->occurs.depending_on ) - { - cbl_field_t *depending_on = cbl_field_of(symbol_at(parent->occurs.depending_on)); - get_integer_value(value64, depending_on); - IF( subscript, ge_op, value64 ) - { - gg_assign(var_decl_odo_violation, integer_one_node); - } - ELSE - ENDIF - } - tree augment = gg_multiply(subscript, build_int_cst_type(INT, parent->data.capacity)); - gg_assign(retval, gg_add(retval, gg_cast(SIZE_T, augment))); - } + ENDIF parent = parent_of(parent); } } @@ -458,76 +424,40 @@ get_data_offset_dest(cbl_refer_t &refer, // We have a refmod to deal with static tree refstart = gg_define_variable(LONG, "..gdos_refstart", vs_file_static); - if( process_this_exception(ec_bound_ref_mod_e) ) - { - get_integer_value(value64, - refer.refmod.from->field, - refer_offset_source(*refer.refmod.from), - CHECK_FOR_FRACTIONAL_DIGITS); - IF( var_decl_rdigits, - ne_op, - integer_zero_node ) - { - // refmod offset is not an integer, and has to be - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_one_node)); - } - else - { - rt_error("error: a refmod FROM is not an integer"); - } - } - ELSE - gg_assign(refstart, value64); - ENDIF - } - else + get_integer_value(refstart, + refer.refmod.from->field, + refer_offset_source(*refer.refmod.from), + CHECK_FOR_FRACTIONAL_DIGITS); + IF( var_decl_rdigits, + ne_op, + integer_zero_node ) { - get_integer_value(value64, - refer.refmod.from->field, - refer_offset_source(*refer.refmod.from) - ); - gg_assign(refstart, value64); + // refmod offset is not an integer, and has to be + set_exception_code(ec_bound_ref_mod_e); } + ELSE + ENDIF // Make refstart zero-based: gg_decrement(refstart); - if( process_this_exception(ec_bound_ref_mod_e) ) + IF( refstart, lt_op, gg_cast(LONG, integer_zero_node) ) + { + set_exception_code(ec_bound_ref_mod_e); + gg_assign(refstart, build_int_cst_type(TREE_TYPE(refstart), 0)); + } + ELSE { - IF( refstart, lt_op, gg_cast(LONG, integer_zero_node) ) + tree capacity = get_any_capacity(refer.field); + IF( refstart, gt_op, gg_cast(LONG, capacity) ) { - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_zero_node)); - } - else - { - rt_error("error: refmod FROM is less than one"); - } + set_exception_code(ec_bound_ref_mod_e); + gg_assign(refstart, build_int_cst_type(TREE_TYPE(refstart), 0)); } ELSE - { - IF( refstart, gt_op, build_int_cst_type(LONG, refer.field->data.capacity) ) - { - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_zero_node)); - } - else - { - rt_error("error: refmod FROM is too large"); - } - } - ELSE - ENDIF - } ENDIF } + ENDIF // We have a good refstart gg_assign(retval, gg_add(retval, gg_cast(SIZE_T, refstart))); @@ -601,42 +531,23 @@ get_data_offset_source(cbl_refer_t &refer, cbl_internal_error("Too many subscripts"); } // Pick up the integer value of the subscript: -// static tree subscript = gg_define_variable(LONG, "..gdos_subscript", vs_file_static); tree subscript = gg_define_variable(LONG); - if( process_this_exception(ec_bound_subscript_e) ) + get_integer_value(subscript, + refer.subscripts[i].field, + refer_offset_source(refer.subscripts[i]), + CHECK_FOR_FRACTIONAL_DIGITS); + IF( var_decl_rdigits, + ne_op, + integer_zero_node ) { - get_integer_value(value64, - refer.subscripts[i].field, - refer_offset_source(refer.subscripts[i]), - CHECK_FOR_FRACTIONAL_DIGITS); - IF( var_decl_rdigits, - ne_op, - integer_zero_node ) - { - if( enabled_exceptions.match(ec_bound_subscript_e) ) - { - // The subscript isn't an integer - SET_EXCEPTION_CODE(ec_bound_subscript_e); - gg_assign(subscript, gg_cast(TREE_TYPE(subscript), integer_zero_node)); - } - else - { - rt_error("error: a table subscript is not an integer"); - } - } - ELSE - { - gg_assign(subscript, gg_cast(TREE_TYPE(subscript), value64)); - } - ENDIF + // The subscript isn't an integer + set_exception_code(ec_bound_subscript_e); } - else + ELSE { - get_integer_value(subscript, - refer.subscripts[i].field, - refer_offset_source(refer.subscripts[i])); } + ENDIF // gg_printf("%s(): We have a subscript of %d from %s\n", // gg_string_literal(__func__), @@ -661,74 +572,46 @@ get_data_offset_source(cbl_refer_t &refer, // Make it zero-based: gg_decrement(subscript); - if( process_this_exception(ec_bound_subscript_e) ) + // gg_printf("process_this_exception is true\n", NULL_TREE); + IF( subscript, lt_op, gg_cast(TREE_TYPE(subscript), integer_zero_node) ) + { + // The subscript is too small + set_exception_code(ec_bound_subscript_e); + gg_assign(subscript, build_int_cst_type(TREE_TYPE(subscript), 0)); + } + ELSE { - // gg_printf("process_this_exception is true\n", NULL_TREE); - IF( subscript, lt_op, gg_cast(TREE_TYPE(subscript), integer_zero_node) ) + // gg_printf("parent->occurs.ntimes() is %d\n", build_int_cst_type(INT, parent->occurs.ntimes()), NULL_TREE); + IF( subscript, + ge_op, + build_int_cst_type(TREE_TYPE(subscript), parent->occurs.ntimes()) ) { - // The subscript is too small - SET_EXCEPTION_CODE(ec_bound_subscript_e); - gg_assign(subscript, gg_cast(TREE_TYPE(subscript), integer_zero_node)); + // The subscript is too large + set_exception_code(ec_bound_subscript_e); + gg_assign(subscript, build_int_cst_type(TREE_TYPE(subscript), 0)); } ELSE { - // gg_printf("parent->occurs.ntimes() is %d\n", build_int_cst_type(INT, parent->occurs.ntimes()), NULL_TREE); - IF( subscript, - ge_op, - build_int_cst_type(TREE_TYPE(subscript), parent->occurs.ntimes()) ) + // We have a good subscript: + // Check for an ODO violation: + if( parent->occurs.depending_on ) { - // The subscript is too large - if( enabled_exceptions.match(ec_bound_subscript_e) ) + cbl_field_t *depending_on = cbl_field_of(symbol_at(parent->occurs.depending_on)); + get_integer_value(value64, depending_on); + IF( subscript, ge_op, value64 ) { - SET_EXCEPTION_CODE(ec_bound_subscript_e); - gg_assign(subscript, gg_cast(TREE_TYPE(subscript), integer_zero_node)); - } - else - { - rt_error("error: table subscript is too large"); + gg_assign(var_decl_odo_violation, integer_one_node); } + ELSE + ENDIF } - ELSE - { - // We have a good subscript: - // Check for an ODO violation: - if( parent->occurs.depending_on ) - { - cbl_field_t *depending_on = cbl_field_of(symbol_at(parent->occurs.depending_on)); - get_integer_value(value64, depending_on); - IF( subscript, ge_op, value64 ) - { - gg_assign(var_decl_odo_violation, integer_one_node); - } - ELSE - ENDIF - } - tree augment = gg_multiply(subscript, build_int_cst_type(INT, parent->data.capacity)); - gg_assign(retval, gg_add(retval, gg_cast(SIZE_T, augment))); - } - ENDIF + tree augment = gg_multiply(subscript, get_any_capacity(parent)); + gg_assign(retval, gg_add(retval, gg_cast(SIZE_T, augment))); } ENDIF } - else - { - // Assume a good subscript: - // Check for an ODO violation: - if( parent->occurs.depending_on ) - { - cbl_field_t *depending_on = cbl_field_of(symbol_at(parent->occurs.depending_on)); - get_integer_value(value64, depending_on); - IF( subscript, ge_op, value64 ) - { - gg_assign(var_decl_odo_violation, integer_one_node); - } - ELSE - ENDIF - } - tree augment = gg_multiply(subscript, build_int_cst_type(INT, parent->data.capacity)); - gg_assign(retval, gg_add(retval, gg_cast(SIZE_T, augment))); - } + ENDIF parent = parent_of(parent); } } @@ -738,76 +621,40 @@ get_data_offset_source(cbl_refer_t &refer, // We have a refmod to deal with static tree refstart = gg_define_variable(LONG, "..gdo_refstart", vs_file_static); - if( process_this_exception(ec_bound_ref_mod_e) ) - { - get_integer_value(value64, - refer.refmod.from->field, - refer_offset_source(*refer.refmod.from), - CHECK_FOR_FRACTIONAL_DIGITS); - IF( var_decl_rdigits, - ne_op, - integer_zero_node ) - { - // refmod offset is not an integer, and has to be - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_one_node)); - } - else - { - rt_error("error: a refmod FROM is not an integer"); - } - } - ELSE - gg_assign(refstart, value64); - ENDIF - } - else + get_integer_value(refstart, + refer.refmod.from->field, + refer_offset_source(*refer.refmod.from), + CHECK_FOR_FRACTIONAL_DIGITS); + IF( var_decl_rdigits, + ne_op, + integer_zero_node ) { - get_integer_value(value64, - refer.refmod.from->field, - refer_offset_source(*refer.refmod.from) - ); - gg_assign(refstart, value64); + // refmod offset is not an integer, and has to be + set_exception_code(ec_bound_ref_mod_e); } + ELSE + ENDIF // Make refstart zero-based: gg_decrement(refstart); - if( process_this_exception(ec_bound_ref_mod_e) ) + IF( refstart, lt_op, gg_cast(LONG, integer_zero_node) ) { - IF( refstart, lt_op, gg_cast(LONG, integer_zero_node) ) + set_exception_code(ec_bound_ref_mod_e); + gg_assign(refstart, gg_cast(LONG, integer_zero_node)); + } + ELSE + { + tree capacity = get_any_capacity(refer.field); + IF( refstart, gt_op, gg_cast(LONG, capacity) ) { - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_zero_node)); - } - else - { - rt_error("error: refmod FROM is less than one"); - } + set_exception_code(ec_bound_ref_mod_e); + gg_assign(refstart, build_int_cst_type(TREE_TYPE(refstart), 0)); } ELSE - { - IF( refstart, gt_op, build_int_cst_type(LONG, refer.field->data.capacity) ) - { - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_zero_node)); - } - else - { - rt_error("error: refmod FROM is too large"); - } - } - ELSE - ENDIF - } ENDIF } + ENDIF // We have a good refstart gg_assign(retval, gg_add(retval, gg_cast(SIZE_T, refstart))); @@ -933,7 +780,7 @@ get_binary_value( tree value, // This is the we-are-done pointer gg_assign(pend, gg_add( pointer, - build_int_cst_type(SIZE_T, field->data.capacity))); + get_any_capacity(field))); static tree signbyte = gg_define_variable(UCHAR, "..gbv_signbyte", vs_file_static); @@ -2123,193 +1970,105 @@ refer_refmod_length(cbl_refer_t &refer) if( refer.refmod.from || refer.refmod.len ) { // First, check for compile-time errors - bool any_length = !!(refer.field->attr & any_length_e); - tree rt_capacity; - static tree value64 = gg_define_variable(LONG, "..rrl_value64", vs_file_static); static tree refstart = gg_define_variable(LONG, "..rrl_refstart", vs_file_static); static tree reflen = gg_define_variable(LONG, "..rrl_reflen", vs_file_static); - if( any_length ) - { - rt_capacity = - gg_cast(LONG, - member(refer.field->var_decl_node, "capacity")); - } - else - { - rt_capacity = - build_int_cst_type(LONG, refer.field->data.capacity); - } + tree rt_capacity = get_any_capacity(refer.field); gg_assign(reflen, gg_cast(TREE_TYPE(reflen), integer_one_node)); - if( process_this_exception(ec_bound_ref_mod_e) ) - { - get_integer_value(value64, - refer.refmod.from->field, - refer_offset_source(*refer.refmod.from), - CHECK_FOR_FRACTIONAL_DIGITS); - IF( var_decl_rdigits, - ne_op, - integer_zero_node ) - { - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_one_node)); - } - else - { - rt_error("a refmod FROM value is not an integer"); - } - } - ELSE - gg_assign(refstart, value64); - ENDIF - } - else + get_integer_value(refstart, + refer.refmod.from->field, + refer_offset_source(*refer.refmod.from), + CHECK_FOR_FRACTIONAL_DIGITS); + IF( var_decl_rdigits, + ne_op, + integer_zero_node ) { - get_integer_value(value64, - refer.refmod.from->field, - refer_offset_source(*refer.refmod.from) - ); - gg_assign(refstart, value64); + set_exception_code(ec_bound_ref_mod_e); + gg_assign(refstart, gg_cast(LONG, integer_one_node)); } + ELSE + ENDIF // Make refstart zero-based: gg_decrement(refstart); - if( process_this_exception(ec_bound_ref_mod_e) ) + IF( refstart, lt_op, build_int_cst_type(LONG, 0 ) ) { - IF( refstart, lt_op, build_int_cst_type(LONG, 0 ) ) + set_exception_code(ec_bound_ref_mod_e); + gg_assign(refstart, gg_cast(LONG, integer_zero_node)); + } + ELSE + { + IF( refstart, gt_op, gg_cast(TREE_TYPE(refstart), rt_capacity) ) { - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_zero_node)); - } - else - { - rt_error("a refmod FROM value is less than zero"); - } + set_exception_code(ec_bound_ref_mod_e); + gg_assign(refstart, gg_cast(LONG, integer_zero_node)); } ELSE { - IF( refstart, gt_op, rt_capacity ) + if( refer.refmod.len ) { - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) + get_integer_value(reflen, + refer.refmod.len->field, + refer_offset_source(*refer.refmod.len), + CHECK_FOR_FRACTIONAL_DIGITS); + IF( var_decl_rdigits, + ne_op, + integer_zero_node ) { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(refstart, gg_cast(LONG, integer_zero_node)); + // length is not an integer + set_exception_code(ec_bound_ref_mod_e); + gg_assign(reflen, gg_cast(LONG, integer_one_node)); } - else + ELSE { - rt_error("a refmod FROM value is too large"); } - } - ELSE - { - if( refer.refmod.len ) - { - get_integer_value(value64, - refer.refmod.len->field, - refer_offset_source(*refer.refmod.len), - CHECK_FOR_FRACTIONAL_DIGITS); - IF( var_decl_rdigits, - ne_op, - integer_zero_node ) - { - // length is not an integer - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(reflen, gg_cast(LONG, integer_one_node)); - } - else - { - rt_error("a refmod LENGTH is not an integer"); - } - } - ELSE - { - gg_assign(reflen, gg_cast(LONG, value64)); - } - ENDIF + ENDIF - IF( reflen, lt_op, gg_cast(LONG, integer_one_node) ) + IF( reflen, lt_op, gg_cast(LONG, integer_one_node) ) + { + // length is too small + set_exception_code(ec_bound_ref_mod_e); + gg_assign(reflen, gg_cast(LONG, integer_one_node)); + } + ELSE + { + IF( gg_add(refstart, reflen), + gt_op, + gg_cast(TREE_TYPE(refstart), rt_capacity) ) { - // length is too small - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - gg_assign(reflen, gg_cast(LONG, integer_one_node)); - } - else - { - rt_error("a refmod LENGTH is less than one"); - } + // Start + Length is too large + set_exception_code(ec_bound_ref_mod_e); + + // Our intentions are honorable. But at this point, where + // we notice that start + length is too long, the + // get_data_offset_source routine has already been run and + // it's too late to actually change the refstart. There are + // theoretical solutions to this -- mainly, + // get_data_offset_source needs to check the start + len for + // validity. But I am not going to do it now. Think of this + // as the TODO item. + gg_assign(refstart, gg_cast(LONG, integer_zero_node)); + gg_assign(reflen, gg_cast(LONG, integer_one_node)); } ELSE - { - IF( gg_add(refstart, reflen), - gt_op, - rt_capacity ) - { - // Start + Length is too large - if( enabled_exceptions.match(ec_bound_ref_mod_e) ) - { - SET_EXCEPTION_CODE(ec_bound_ref_mod_e); - - // Our intentions are honorable. But at this point, where - // we notice that start + length is too long, the - // get_data_offset_source routine has already been run and - // it's too late to actually change the refstart. There are - // theoretical solutions to this -- mainly, - // get_data_offset_source needs to check the start + len for - // validity. But I am not going to do it now. Think of this - // as the TODO item. - gg_assign(refstart, gg_cast(LONG, integer_zero_node)); - gg_assign(reflen, gg_cast(LONG, integer_one_node)); - } - else - { - rt_error("refmod START + LENGTH is too large"); - } - } - ELSE - ENDIF - } ENDIF } - else - { - // There is no refmod length, so we default to the remaining characters - tree subtract_expr = gg_subtract( rt_capacity, - refstart); - gg_assign(reflen, subtract_expr); - } + ENDIF + } + else + { + // There is no refmod length, so we default to the remaining characters + tree subtract_expr = gg_subtract( rt_capacity, + refstart); + gg_assign(reflen, subtract_expr); } - ENDIF } ENDIF } - else - { - if( refer.refmod.len ) - { - get_integer_value(value64, - refer.refmod.len->field, - refer_offset_source(*refer.refmod.len) - ); - gg_assign(reflen, gg_cast(LONG, value64)); - } - else - { - // There is no refmod length, so we default to the remaining characters - gg_assign(reflen, gg_subtract(rt_capacity, - refstart)); - } - } + ENDIF // Arrive here with valid values for refstart and reflen: @@ -2346,73 +2105,42 @@ refer_fill_depends(cbl_refer_t &refer) // depending_on->name); static tree value64 = gg_define_variable(LONG, "..rfd_value64", vs_file_static); - if( process_this_exception(ec_bound_odo_e) ) + get_integer_value(value64, + depending_on, + NULL, + CHECK_FOR_FRACTIONAL_DIGITS); + IF( var_decl_rdigits, ne_op, integer_zero_node ) { - get_integer_value(value64, - depending_on, - NULL, - CHECK_FOR_FRACTIONAL_DIGITS); - IF( var_decl_rdigits, ne_op, integer_zero_node ) - { - // This needs to evaluate to an integer - if( enabled_exceptions.match(ec_bound_odo_e) ) - { - SET_EXCEPTION_CODE(ec_bound_odo_e); - gg_assign(value64, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.upper)); - } - else - { - rt_error("DEPENDING ON is not an integer"); - } - } - ELSE - ENDIF + // This needs to evaluate to an integer + set_exception_code(ec_bound_odo_e); + gg_assign(value64, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.upper)); } - else + ELSE + ENDIF + + IF( value64, gt_op, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.upper) ) { - get_integer_value(value64, depending_on); + set_exception_code(ec_bound_odo_e); + gg_assign(value64, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.upper)); } - - if( process_this_exception(ec_bound_odo_e) ) + ELSE { - IF( value64, gt_op, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.upper) ) + IF( value64, lt_op, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.lower) ) { - SET_EXCEPTION_CODE(ec_bound_odo_e); - gg_assign(value64, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.upper)); + set_exception_code(ec_bound_odo_e); + gg_assign(value64, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.lower)); } ELSE + ENDIF + IF( value64, lt_op, gg_cast(TREE_TYPE(value64), integer_zero_node) ) { - IF( value64, lt_op, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.lower) ) - { - if( enabled_exceptions.match(ec_bound_odo_e) ) - { - SET_EXCEPTION_CODE(ec_bound_odo_e); - gg_assign(value64, build_int_cst_type(TREE_TYPE(value64), odo->occurs.bounds.lower)); - } - else - { - rt_error("DEPENDING ON is less than OCCURS lower limit"); - } - } - ELSE - ENDIF - IF( value64, lt_op, gg_cast(TREE_TYPE(value64), integer_zero_node) ) - { - if( enabled_exceptions.match(ec_bound_odo_e) ) - { - SET_EXCEPTION_CODE(ec_bound_odo_e); - gg_assign(value64, gg_cast(TREE_TYPE(value64), integer_zero_node)); - } - else - { - rt_error("DEPENDING ON is greater than OCCURS upper limit"); - } - } - ELSE - ENDIF + set_exception_code(ec_bound_odo_e); + gg_assign(value64, gg_cast(TREE_TYPE(value64), integer_zero_node)); } + ELSE ENDIF } + ENDIF // value64 is >= zero and < bounds.upper // We multiply the ODO value by the size of the data capacity to get the @@ -2448,22 +2176,12 @@ refer_offset_dest(cbl_refer_t &refer) tree retval = gg_define_variable(SIZE_T); gg_assign(retval, get_data_offset_dest(refer)); - if( process_this_exception(ec_bound_odo_e) ) + IF( var_decl_odo_violation, ne_op, integer_zero_node ) { - IF( var_decl_odo_violation, ne_op, integer_zero_node ) - { - if( enabled_exceptions.match(ec_bound_odo_e) ) - { - SET_EXCEPTION_CODE(ec_bound_odo_e); - } - else - { - rt_error("receiving item subscript not in DEPENDING ON range"); - } - } - ELSE - ENDIF + set_exception_code(ec_bound_odo_e); } + ELSE + ENDIF return retval; } @@ -2482,14 +2200,7 @@ refer_size_dest(cbl_refer_t &refer) { // When the refer has no modifications, we return zero, which is interpreted // as "use the original length" - if( refer.field->attr & (intermediate_e | any_length_e) ) - { - return member(refer.field->var_decl_node, "capacity"); - } - else - { - return build_int_cst_type(SIZE_T, refer.field->data.capacity); - } + return get_any_capacity(refer.field); } // Step the first: Get the actual full length: @@ -2546,22 +2257,12 @@ refer_offset_source(cbl_refer_t &refer, gg_assign(var_decl_odo_violation, integer_zero_node); gg_assign(retval, get_data_offset_source(refer, pflags)); - if( process_this_exception(ec_bound_odo_e) ) + IF( var_decl_odo_violation, ne_op, integer_zero_node ) { - IF( var_decl_odo_violation, ne_op, integer_zero_node ) - { - if( enabled_exceptions.match(ec_bound_odo_e) ) - { - SET_EXCEPTION_CODE(ec_bound_odo_e); - } - else - { - rt_error("sending item subscript not in DEPENDING ON range"); - } - } - ELSE - ENDIF + set_exception_code(ec_bound_odo_e); } + ELSE + ENDIF return retval; } diff --git a/gcc/common.opt b/gcc/common.opt index e3fa0da..d10a6b7 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1061,6 +1061,9 @@ Driver Undocumented ; 20: Fix mangling of lambdas in static data member initializers. ; Default in G++ 15. ; +; 21: +; Default in G++ 16. +; ; Additional positive integers will be assigned as new versions of ; the ABI become the default version of the ABI. fabi-version= diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc index b34409a..15df22d 100644 --- a/gcc/common/config/riscv/riscv-common.cc +++ b/gcc/common/config/riscv/riscv-common.cc @@ -218,6 +218,37 @@ static const riscv_implied_info_t riscv_implied_info[] = { return subset_list->xlen () == 32 && subset_list->lookup ("f"); }}, + {"zca", "c", + [] (const riscv_subset_list *subset_list) -> bool + { + /* For RV32 Zca implies C for one of these combinations of + extensions: Zca, F_Zca_Zcf and FD_Zca_Zcf_Zcd. */ + if (subset_list->xlen () == 32) + { + if (subset_list->lookup ("d")) + return subset_list->lookup ("zcf") && subset_list->lookup ("zcd"); + + if (subset_list->lookup ("f")) + return subset_list->lookup ("zcf"); + + return true; + } + + /* For RV64 Zca implies C for one of these combinations of + extensions: Zca and FD_Zca_Zcd (Zcf is not available + for RV64). */ + if (subset_list->xlen () == 64) + { + if (subset_list->lookup ("d")) + return subset_list->lookup ("zcd"); + + return true; + } + + /* Do nothing for future RV128 specification. Behaviour + for this case is not yet well defined. */ + return false; + }}, {"smaia", "ssaia"}, {"smstateen", "ssstateen"}, diff --git a/gcc/config/gcn/gcn.cc b/gcc/config/gcn/gcn.cc index d59e87b..91ce801 100644 --- a/gcc/config/gcn/gcn.cc +++ b/gcc/config/gcn/gcn.cc @@ -6587,8 +6587,8 @@ gcn_hsa_declare_function_name (FILE *file, const char *name, if (avgpr % vgpr_block_size) avgpr += vgpr_block_size - (avgpr % vgpr_block_size); - fputs ("\t.rodata\n" - "\t.p2align\t6\n" + switch_to_section (readonly_data_section); + fputs ("\t.p2align\t6\n" "\t.amdhsa_kernel\t", file); assemble_name (file, name); fputs ("\n", file); @@ -6707,7 +6707,7 @@ gcn_hsa_declare_function_name (FILE *file, const char *name, fputs (" .end_amdgpu_metadata\n", file); #endif - fputs ("\t.text\n", file); + switch_to_section (current_function_section ()); fputs ("\t.align\t256\n", file); fputs ("\t.type\t", file); assemble_name (file, name); diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index 3b4dfd9..78df3d9 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -25375,14 +25375,32 @@ ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, case COND_EXPR: { /* SSE2 conditinal move sequence is: - pcmpgtd %xmm5, %xmm0 + pcmpgtd %xmm5, %xmm0 (accounted separately) pand %xmm0, %xmm2 pandn %xmm1, %xmm0 por %xmm2, %xmm0 while SSE4 uses cmp + blend - and AVX512 masked moves. */ - - int ninsns = TARGET_SSE4_1 ? 2 : 4; + and AVX512 masked moves. + + The condition is accounted separately since we usually have + p = a < b + c = p ? x : y + and we will account first statement as setcc. Exception is when + p is loaded from memory as bool and then we will not acocunt + the compare, but there is no way to check for this. */ + + int ninsns = TARGET_SSE4_1 ? 1 : 3; + + /* If one of parameters is 0 or -1 the sequence will be simplified: + (if_true & mask) | (if_false & ~mask) -> if_true & mask */ + if (ninsns > 1 + && (zerop (gimple_assign_rhs2 (stmt_info->stmt)) + || zerop (gimple_assign_rhs3 (stmt_info->stmt)) + || integer_minus_onep + (gimple_assign_rhs2 (stmt_info->stmt)) + || integer_minus_onep + (gimple_assign_rhs3 (stmt_info->stmt)))) + ninsns = 1; if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode)) stmt_cost = ninsns * ix86_cost->sse_op; @@ -25393,8 +25411,8 @@ ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, else if (VECTOR_MODE_P (mode)) stmt_cost = ix86_vec_cost (mode, ninsns * ix86_cost->sse_op); else - /* compare + cmov. */ - stmt_cost = ix86_cost->add * 2; + /* compare (accounted separately) + cmov. */ + stmt_cost = ix86_cost->add; } break; @@ -25416,9 +25434,18 @@ ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, { stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op); /* vpmin was introduced in SSE3. - SSE2 needs pcmpgtd + pand + pandn + pxor. */ + SSE2 needs pcmpgtd + pand + pandn + pxor. + If one of parameters is 0 or -1 the sequence is simplified + to pcmpgtd + pand. */ if (!TARGET_SSSE3) - stmt_cost *= 4; + { + if (zerop (gimple_assign_rhs2 (stmt_info->stmt)) + || integer_minus_onep + (gimple_assign_rhs2 (stmt_info->stmt))) + stmt_cost *= 2; + else + stmt_cost *= 4; + } } else /* cmp + cmov. */ diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc index d82b16e..e3edf85 100644 --- a/gcc/config/s390/s390.cc +++ b/gcc/config/s390/s390.cc @@ -14496,7 +14496,21 @@ s390_call_saved_register_used (tree call_expr) for (reg = 0; reg < nregs; reg++) if (!call_used_or_fixed_reg_p (reg + REGNO (parm_rtx))) - return true; + { + rtx parm; + /* Allow passing through unmodified value from caller, + see PR119873. */ + if (TREE_CODE (parameter) == SSA_NAME + && SSA_NAME_IS_DEFAULT_DEF (parameter) + && SSA_NAME_VAR (parameter) + && TREE_CODE (SSA_NAME_VAR (parameter)) == PARM_DECL + && (parm = DECL_INCOMING_RTL (SSA_NAME_VAR (parameter))) + && REG_P (parm) + && REGNO (parm) == REGNO (parm_rtx) + && REG_NREGS (parm) == REG_NREGS (parm_rtx)) + break; + return true; + } } else if (GET_CODE (parm_rtx) == PARALLEL) { @@ -14510,7 +14524,17 @@ s390_call_saved_register_used (tree call_expr) gcc_assert (REG_NREGS (r) == 1); if (!call_used_or_fixed_reg_p (REGNO (r))) - return true; + { + rtx parm; + if (TREE_CODE (parameter) == SSA_NAME + && SSA_NAME_IS_DEFAULT_DEF (parameter) + && SSA_NAME_VAR (parameter) + && TREE_CODE (SSA_NAME_VAR (parameter)) == PARM_DECL + && (parm = DECL_INCOMING_RTL (SSA_NAME_VAR (parameter))) + && rtx_equal_p (parm_rtx, parm)) + break; + return true; + } } } } @@ -14543,8 +14567,9 @@ s390_function_ok_for_sibcall (tree decl, tree exp) return false; /* Register 6 on s390 is available as an argument register but unfortunately - "caller saved". This makes functions needing this register for arguments - not suitable for sibcalls. */ + "caller saved". This makes functions needing this register for arguments + not suitable for sibcalls, unless the same value is passed from the + caller. */ return !s390_call_saved_register_used (exp); } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d9f0298..cd128e2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2025-04-24 Jason Merrill <jason@redhat.com> + + PR c++/116954 + * contracts.cc (remove_contract_attributes): Return early if + not enabled. + 2025-04-22 Nathaniel Shead <nathanieloshead@gmail.com> * name-lookup.cc (lookup_imported_hidden_friend): Remove diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7798efb..856202c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6755,8 +6755,14 @@ struct GTY((chain_next ("%h.next"))) tinst_level { /* The location where the template is instantiated. */ location_t locus; - /* errorcount + sorrycount when we pushed this level. */ - unsigned short errors; + /* errorcount + sorrycount when we pushed this level. If the value + overflows, it will always seem like we currently have more errors, so we + will limit template recursion even from non-erroneous templates. In a TU + with over 32k errors, that's fine. */ + unsigned short errors : 15; + + /* set in pop_tinst_level if there have been errors since we pushed. */ + bool had_errors : 1; /* Count references to this object. If refcount reaches refcount_infinity value, we don't increment or decrement the diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index b2e0ecd..a2bed9f 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -348,7 +348,11 @@ insert_capture_proxy (tree var) /* And put a DECL_EXPR in the STATEMENT_LIST for the same block. */ var = build_stmt (DECL_SOURCE_LOCATION (var), DECL_EXPR, var); - tree stmt_list = (*stmt_list_stack)[1]; + /* The first stmt_list is from start_preparsed_function. Then there's a + possible stmt_list from begin_eh_spec_block, then the one from the + lambda's outer {}. */ + unsigned index = 1 + use_eh_spec_block (current_function_decl); + tree stmt_list = (*stmt_list_stack)[index]; gcc_assert (stmt_list); append_to_statement_list_force (var, &stmt_list); } @@ -1859,11 +1863,10 @@ prune_lambda_captures (tree body) cp_walk_tree_without_duplicates (&body, mark_const_cap_r, &const_vars); tree bind_expr = expr_single (DECL_SAVED_TREE (lambda_function (lam))); - if (bind_expr && TREE_CODE (bind_expr) == MUST_NOT_THROW_EXPR) + bool noexcept_p = (bind_expr + && TREE_CODE (bind_expr) == MUST_NOT_THROW_EXPR); + if (noexcept_p) bind_expr = expr_single (TREE_OPERAND (bind_expr, 0)); - /* FIXME: We don't currently handle noexcept lambda captures correctly, - so bind_expr may not be set; see PR c++/119764. */ - gcc_assert (!bind_expr || TREE_CODE (bind_expr) == BIND_EXPR); tree *fieldp = &TYPE_FIELDS (LAMBDA_EXPR_CLOSURE (lam)); for (tree *capp = &LAMBDA_EXPR_CAPTURE_LIST (lam); *capp; ) @@ -1872,11 +1875,23 @@ prune_lambda_captures (tree body) if (tree var = var_to_maybe_prune (cap)) { tree **use = const_vars.get (var); - if (use && TREE_CODE (**use) == DECL_EXPR) + if (TREE_CODE (**use) == DECL_EXPR) { /* All uses of this capture were folded away, leaving only the proxy declaration. */ + if (noexcept_p) + { + /* We didn't handle noexcept lambda captures correctly before + the fix for PR c++/119764. */ + if (abi_version_crosses (21)) + warning_at (location_of (lam), OPT_Wabi, "%qD is no longer" + " captured in noexcept lambda in ABI v21 " + "(GCC 16)", var); + if (!abi_version_at_least (21)) + goto next; + } + /* Splice the capture out of LAMBDA_EXPR_CAPTURE_LIST. */ *capp = TREE_CHAIN (cap); @@ -1894,14 +1909,11 @@ prune_lambda_captures (tree body) /* And maybe out of the vars declared in the containing BIND_EXPR, if it's listed there. */ - if (bind_expr) - { - tree *bindp = &BIND_EXPR_VARS (bind_expr); - while (*bindp && *bindp != DECL_EXPR_DECL (**use)) - bindp = &DECL_CHAIN (*bindp); - if (*bindp) - *bindp = DECL_CHAIN (*bindp); - } + tree *bindp = &BIND_EXPR_VARS (bind_expr); + while (*bindp && *bindp != DECL_EXPR_DECL (**use)) + bindp = &DECL_CHAIN (*bindp); + if (*bindp) + *bindp = DECL_CHAIN (*bindp); /* And remove the capture proxy declaration. */ **use = void_node; @@ -1909,6 +1921,7 @@ prune_lambda_captures (tree body) } } + next: capp = &TREE_CHAIN (cap); } } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index a71705f..e8d342f 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -11418,6 +11418,7 @@ push_tinst_level_loc (tree tldcl, tree targs, location_t loc) new_level->targs = targs; new_level->locus = loc; new_level->errors = errorcount + sorrycount; + new_level->had_errors = false; new_level->next = NULL; new_level->refcount = 0; new_level->path = new_level->visible = nullptr; @@ -11468,6 +11469,9 @@ pop_tinst_level (void) /* Restore the filename and line number stashed away when we started this instantiation. */ input_location = current_tinst_level->locus; + if (unsigned errs = errorcount + sorrycount) + if (errs > current_tinst_level->errors) + current_tinst_level->had_errors = true; set_refcount_ptr (current_tinst_level, current_tinst_level->next); --tinst_depth; } @@ -11487,7 +11491,7 @@ reopen_tinst_level (struct tinst_level *level) set_refcount_ptr (current_tinst_level, level); pop_tinst_level (); - if (current_tinst_level) + if (current_tinst_level && !current_tinst_level->had_errors) current_tinst_level->errors = errorcount+sorrycount; tree decl = level->maybe_get_node (); @@ -28072,7 +28076,9 @@ instantiate_pending_templates (int retries) tree instantiation = reopen_tinst_level ((*t)->tinst); bool complete = false; - if (TYPE_P (instantiation)) + if (limit_bad_template_recursion (instantiation)) + /* Do nothing. */; + else if (TYPE_P (instantiation)) { if (!COMPLETE_TYPE_P (instantiation)) { diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index bda22d1..7c6a415 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2025-04-23 Andre Vehreschild <vehre@gcc.gnu.org> + + PR fortran/119200 + * check.cc (gfc_check_lcobound): Use locus from intrinsic_where. + (gfc_check_image_index): Same. + (gfc_check_num_images): Same. + (gfc_check_team_number): Same. + (gfc_check_this_image): Same. + (gfc_check_ucobound): Same. + 2025-04-22 Andre Vehreschild <vehre@gcc.gnu.org> * match.cc (match_exit_cycle): Allow to exit team block. diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index ee48a82..43bd7be 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -8079,13 +8079,13 @@ gfc_generate_function_code (gfc_namespace * ns) || sym->result->ts.u.derived->attr.alloc_comp || sym->result->ts.u.derived->attr.pointer_comp)) || (sym->result->ts.type == BT_CLASS - && (CLASS_DATA (sym)->attr.allocatable - || CLASS_DATA (sym)->attr.class_pointer + && (CLASS_DATA (sym->result)->attr.allocatable + || CLASS_DATA (sym->result)->attr.class_pointer || CLASS_DATA (sym->result)->attr.alloc_comp || CLASS_DATA (sym->result)->attr.pointer_comp)))) { artificial_result_decl = true; - result = gfc_get_fake_result_decl (sym, 0); + result = gfc_get_fake_result_decl (sym->result, 0); } if (result != NULL_TREE && sym->attr.function && !sym->attr.pointer) diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index 19e5669b..8d9448e 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -8145,7 +8145,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, goto end_pointer_check; tmp = parmse.expr; - if (fsym && fsym->ts.type == BT_CLASS) + if (fsym && fsym->ts.type == BT_CLASS && !attr.proc_pointer) { if (POINTER_TYPE_P (TREE_TYPE (tmp))) tmp = build_fold_indirect_ref_loc (input_location, tmp); @@ -10912,9 +10912,11 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2) gfc_init_se (&lse, NULL); /* Usually testing whether this is not a proc pointer assignment. */ - non_proc_ptr_assign = !(gfc_expr_attr (expr1).proc_pointer - && expr2->expr_type == EXPR_VARIABLE - && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE); + non_proc_ptr_assign + = !(gfc_expr_attr (expr1).proc_pointer + && ((expr2->expr_type == EXPR_VARIABLE + && expr2->symtree->n.sym->attr.flavor == FL_PROCEDURE) + || expr2->expr_type == EXPR_NULL)); /* Check whether the expression is a scalar or not; we cannot use expr1->rank as it can be nonzero for proc pointers. */ diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc index 3fccc62..b354fb1 100644 --- a/gcc/ipa-icf.cc +++ b/gcc/ipa-icf.cc @@ -233,16 +233,6 @@ void sem_item::set_hash (hashval_t hash) hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache; -/* Semantic function constructor that uses STACK as bitmap memory stack. */ - -sem_function::sem_function (bitmap_obstack *stack) - : sem_item (FUNC, stack), memory_access_types (), m_alias_sets_hash (0), - m_checker (NULL), m_compared_func (NULL) -{ - bb_sizes.create (0); - bb_sorted.create (0); -} - sem_function::sem_function (cgraph_node *node, bitmap_obstack *stack) : sem_item (FUNC, node, stack), memory_access_types (), m_alias_sets_hash (0), m_checker (NULL), m_compared_func (NULL) @@ -1367,7 +1357,6 @@ sem_function::init (ipa_icf_gimple::func_checker *checker) gcc_assert (SSANAMES (func)); ssa_names_size = SSANAMES (func)->length (); - node = node; decl = fndecl; region_tree = func->eh->region_tree; @@ -1647,10 +1636,6 @@ sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target) return (*bb_dict)[source] == target; } -sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack) -{ -} - sem_variable::sem_variable (varpool_node *node, bitmap_obstack *stack) : sem_item (VAR, node, stack) { diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h index c2854ed..4c9094c 100644 --- a/gcc/ipa-icf.h +++ b/gcc/ipa-icf.h @@ -308,8 +308,6 @@ private: class sem_function: public sem_item { public: - /* Semantic function constructor that uses STACK as bitmap memory stack. */ - sem_function (bitmap_obstack *stack); /* Constructor based on callgraph node _NODE. Bitmap STACK is used for memory allocation. */ @@ -419,9 +417,6 @@ private: class sem_variable: public sem_item { public: - /* Semantic variable constructor that uses STACK as bitmap memory stack. */ - sem_variable (bitmap_obstack *stack); - /* Constructor based on callgraph node _NODE. Bitmap STACK is used for memory allocation. */ diff --git a/gcc/m2/ChangeLog b/gcc/m2/ChangeLog index eeb5f66..5290f7c 100644 --- a/gcc/m2/ChangeLog +++ b/gcc/m2/ChangeLog @@ -1,3 +1,39 @@ +2025-04-24 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/119915 + * gm2-libs/FormatStrings.mod (PerformFormatString): Handle + the %u and %x format specifiers in a similar way to the %d + specifier. Avoid using Slice and use Copy instead. + +2025-04-24 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/119914 + * gm2-compiler/M2Check.mod (checkConstMeta): Add check for + Ztype, Rtype and Ctype and unbounded arrays. + (IsZRCType): New procedure function. + (isZRC): Add comment. + * gm2-compiler/M2Quads.mod: + * gm2-compiler/M2Range.mod (gdbinit): New procedure. + (BreakWhenRangeCreated): Ditto. + (CheckBreak): Ditto. + (InitRange): Call CheckBreak. + (Init): Add gdbhook and initialize interactive watch point. + * gm2-compiler/SymbolTable.def (GetNthParamAnyClosest): New + procedure function. + * gm2-compiler/SymbolTable.mod (BreakSym): Remove constant. + (BreakSym): Add Variable. + (stop): Remove. + (gdbhook): New procedure. + (BreakWhenSymCreated): Ditto. + (CheckBreak): Ditto. + (NewSym): Call CheckBreak. + (Init): Add gdbhook and initialize interactive watch point. + (MakeProcedure): Replace guarded call to stop with CheckBreak. + (GetNthParamChoice): New procedure function. + (GetNthParamOrdered): Ditto. + (GetNthParamAnyClosest): Ditto. + (GetOuterModuleScope): Ditto. + 2025-04-11 Gaius Mulley <gaiusmod2@gmail.com> PR modula2/119735 diff --git a/gcc/modulo-sched.cc b/gcc/modulo-sched.cc index 08af5a9..0023467 100644 --- a/gcc/modulo-sched.cc +++ b/gcc/modulo-sched.cc @@ -356,7 +356,13 @@ doloop_register_get (rtx_insn *head, rtx_insn *tail) reg = XEXP (condition, 0); else if (GET_CODE (XEXP (condition, 0)) == PLUS && REG_P (XEXP (XEXP (condition, 0), 0))) - reg = XEXP (XEXP (condition, 0), 0); + { + if (CONST_INT_P (XEXP (condition, 1)) + && INTVAL (XEXP (condition, 1)) == -1) + reg = XEXP (XEXP (condition, 0), 0); + else + return NULL_RTX; + } else gcc_unreachable (); diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index b1537f7..96da438 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,11 @@ +2025-04-23 Joseph Myers <josmyers@redhat.com> + + * gcc.pot: Regenerate. + +2025-04-23 Joseph Myers <josmyers@redhat.com> + + * sv.po: Update. + 2025-04-09 Joseph Myers <josmyers@redhat.com> * de.po: Update. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af49263..47666a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,97 @@ +2025-04-24 Jakub Jelinek <jakub@redhat.com> + Stefan Schulze Frielinghaus <stefansf@gcc.gnu.org> + + PR target/119873 + * gcc.target/s390/pr119873-1.c: New test. + * gcc.target/s390/pr119873-2.c: New test. + * gcc.target/s390/pr119873-3.c: New test. + * gcc.target/s390/pr119873-4.c: New test. + +2025-04-24 Robert Dubner <rdubner@symas.com> + + * cobol.dg/group1/declarative_1.cob: Adjust for repaired exception logic. + +2025-04-24 Jan Hubicka <hubicka@ucw.cz> + + * gcc.target/i386/pr119919.c: New test. + +2025-04-24 Richard Sandiford <richard.sandiford@arm.com> + + PR target/119610 + * g++.dg/torture/pr119610.C: New test. + * g++.target/aarch64/sve/pr119610-sve.C: Likewise. + +2025-04-24 Jakub Jelinek <jakub@redhat.com> + + PR c++/110343 + * gcc.dg/raw-string-1.c: New test. + +2025-04-24 Kyrylo Tkachov <ktkachov@nvidia.com> + + * gcc.dg/completion-2.c: Remove check for default. + +2025-04-24 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/119915 + * gm2/pimlib/run/pass/format2.mod: New test. + +2025-04-24 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/avx512vl-pr103750-1.c: New test. + * gcc.target/i386/avx512f-pr96891-3.c: Adjust testcase. + * gcc.target/i386/avx512f-vpcmpgtuq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpeqq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpequq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpgeq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpgeuq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpgtq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpgtuq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpleq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpleuq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpltq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpltuq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpneqq-1.c: Ditto. + * gcc.target/i386/avx512vl-vpcmpnequq-1.c: Ditto. + +2025-04-24 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/119914 + * gm2/pim/fail/constintarraybyte.mod: New test. + +2025-04-23 Dimitar Dimitrov <dimitar@dinux.eu> + + * g++.dg/no-stack-protector-attr-3.C: Require effective target + fstack_protector. + +2025-04-23 Jan Hubicka <hubicka@ucw.cz> + + * gcc.dg/ipa/ipa-clone-4.c: New file. + * gcc.dg/tree-prof/ipa-cp-1.c: New file. + +2025-04-23 Christophe Lyon <christophe.lyon@linaro.org> + + PR target/71233 + * gcc.target/aarch64/advsimd-intrinsics/vld1x2.c: Enable on arm. + * gcc.target/aarch64/advsimd-intrinsics/vld1x3.c: Likewise. + * gcc.target/aarch64/advsimd-intrinsics/vld1x4.c: Likewise. + * gcc.target/aarch64/advsimd-intrinsics/vst1x2.c: Likewise. + * gcc.target/aarch64/advsimd-intrinsics/vst1x3.c: Likewise. + * gcc.target/aarch64/advsimd-intrinsics/vst1x4.c: Likewise. + +2025-04-23 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * g++.dg/eh/pr119507.C: Skip on sparc*-*-solaris2* && !gas. + +2025-04-23 Tamar Christina <tamar.christina@arm.com> + + PR target/119286 + * gcc.dg/vect/vect-early-break_38.c: Force -march=gfx908 for amdgcn. + +2025-04-23 liuhongt <hongtao.liu@intel.com> + + * gcc.target/i386/blendv-to-maxmin.c: New test. + * gcc.target/i386/blendv-to-pand.c: New test. + 2025-04-22 Jan Hubicka <hubicka@ucw.cz> * gcc.target/i386/pr89618-2.c: XFAIL. diff --git a/gcc/testsuite/cobol.dg/group1/declarative_1.cob b/gcc/testsuite/cobol.dg/group1/declarative_1.cob index 744495a..ec68e9c 100644 --- a/gcc/testsuite/cobol.dg/group1/declarative_1.cob +++ b/gcc/testsuite/cobol.dg/group1/declarative_1.cob @@ -1,14 +1,14 @@ *> { dg-do run } *> { dg-output {Turning EC\-ALL CHECKING OFF \-\- Expecting \+00\.00 from ACOS\(\-3\)(\n|\r\n|\r)} } -*> { dg-output { \+00\.00 TABL\(VSIX\) is 6(\n|\r\n|\r)} } +*> { dg-output { \+00\.00 TABL\(VSIX\) is 1(\n|\r\n|\r)} } *> { dg-output {Turning EC\-ARGUMENT\-FUNCTION CHECKING ON(\n|\r\n|\r)} } *> { dg-output { Expecting \+0\.00 and DECLARATIVE FOR EC\-ARGUMENT\-FUNCTION(\n|\r\n|\r)} } *> { dg-output { DECLARATIVE FOR EC\-ARGUMENT\-FUNCTION(\n|\r\n|\r)} } -*> { dg-output { \+00\.00 TABL\(VSIX\) is 6(\n|\r\n|\r)} } +*> { dg-output { \+00\.00 TABL\(VSIX\) is 1(\n|\r\n|\r)} } *> { dg-output {Turning EC\-ARGUMENT CHECKING ON(\n|\r\n|\r)} } *> { dg-output { Expecting \+0\.00 and DECLARATIVE FOR EC\-ARGUMENT\-FUNCTION(\n|\r\n|\r)} } *> { dg-output { DECLARATIVE FOR EC\-ARGUMENT\-FUNCTION(\n|\r\n|\r)} } -*> { dg-output { \+00\.00 TABL\(VSIX\) is 6(\n|\r\n|\r)} } +*> { dg-output { \+00\.00 TABL\(VSIX\) is 1(\n|\r\n|\r)} } *> { dg-output {Turning EC\-ALL CHECKING ON(\n|\r\n|\r)} } *> { dg-output { Expecting \+0\.00 and DECLARATIVE EC\-ARGUMENT\-FUNCTION(\n|\r\n|\r)} } *> { dg-output { Followed by DECLARATIVE EC\-ALL for TABL\(6\) access(\n|\r\n|\r)} } diff --git a/gcc/testsuite/cobol.dg/group2/88_level_with_FALSE_IS_clause.cob b/gcc/testsuite/cobol.dg/group2/88_level_with_FALSE_IS_clause.cob new file mode 100644 index 0000000..012da75 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/88_level_with_FALSE_IS_clause.cob @@ -0,0 +1,19 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 MYFLD PIC X(6) VALUE "ABCDEF". + 88 MYFLD88 VALUE "ABCDEF" + FALSE IS "OKOKOK". + PROCEDURE DIVISION. + ASTART SECTION. + A01. + SET MYFLD88 TO FALSE + IF MYFLD NOT = "OKOKOK" + DISPLAY MYFLD + END-DISPLAY + END-IF + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/88_level_with_FILLER.cob b/gcc/testsuite/cobol.dg/group2/88_level_with_FILLER.cob new file mode 100644 index 0000000..49157f4 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/88_level_with_FILLER.cob @@ -0,0 +1,20 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FILLER PIC X VALUE SPACE. + 88 X VALUE "X". + PROCEDURE DIVISION. + IF X + DISPLAY "NOT OK" + END-DISPLAY + END-IF + SET X TO TRUE. + IF NOT X + DISPLAY "NOT OK" + END-DISPLAY + END-IF + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/88_level_with_THRU.cob b/gcc/testsuite/cobol.dg/group2/88_level_with_THRU.cob new file mode 100644 index 0000000..005bb64 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/88_level_with_THRU.cob @@ -0,0 +1,86 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 VAR-X PIC X VALUE SPACE. + 88 X VALUE "X". + 88 T-Y VALUE "T" THRU "Y". + 01 VAR-9 PIC 9 VALUE ZERO. + 88 V9 VALUE 9. + 88 V2-4 VALUE 2 THRU 4. + PROCEDURE DIVISION. + IF X + DISPLAY "NOT OK '" VAR-X "' IS X" + END-DISPLAY + END-IF + SET X TO TRUE + IF NOT X + DISPLAY "NOT OK '" VAR-X "' IS NOT X" + END-DISPLAY + END-IF + IF NOT T-Y + DISPLAY "NOT OK '" VAR-X "' IS NOT T-Y" + END-DISPLAY + END-IF + SET T-Y TO TRUE + IF NOT T-Y + DISPLAY "NOT OK '" VAR-X "' IS NOT T-Y" + END-DISPLAY + END-IF + MOVE 'Y' TO VAR-X + IF NOT T-Y + DISPLAY "NOT OK '" VAR-X "' IS NOT T-Y" + END-DISPLAY + END-IF + MOVE 'Z' TO VAR-X + IF T-Y + DISPLAY "NOT OK '" VAR-X "' IS T-Y" + END-DISPLAY + END-IF + MOVE 'A' TO VAR-X + IF T-Y + DISPLAY "NOT OK '" VAR-X "' IS T-Y" + END-DISPLAY + END-IF + IF V9 + DISPLAY "NOT OK '" VAR-9 "' IS V9" + END-DISPLAY + END-IF + SET V9 TO TRUE + IF NOT V9 + DISPLAY "NOT OK '" VAR-9 "' IS NOT V9" + END-DISPLAY + END-IF + SET V2-4 TO TRUE + IF V9 + DISPLAY "NOT OK '" VAR-9 "' IS V9" + END-DISPLAY + END-IF + IF NOT V2-4 + DISPLAY "NOT OK '" VAR-9 "' IS NOT V2-4" + END-DISPLAY + END-IF + MOVE 3 TO VAR-9 + IF NOT V2-4 + DISPLAY "NOT OK '" VAR-9 "' IS NOT V2-4" + END-DISPLAY + END-IF + MOVE 4 TO VAR-9 + IF NOT V2-4 + DISPLAY "NOT OK '" VAR-9 "' IS NOT V2-4" + END-DISPLAY + END-IF + MOVE 5 TO VAR-9 + IF V2-4 + DISPLAY "NOT OK '" VAR-9 "' IS V2-4" + END-DISPLAY + END-IF + MOVE 1 TO VAR-9 + IF V2-4 + DISPLAY "NOT OK '" VAR-9 "' IS V2-4" + END-DISPLAY + END-IF + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ADD_CORRESPONDING.cob b/gcc/testsuite/cobol.dg/group2/ADD_CORRESPONDING.cob new file mode 100644 index 0000000..732d241 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ADD_CORRESPONDING.cob @@ -0,0 +1,39 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 GROUP-1. + 05 FIELD-A PIC 9 VALUE 1. + 05 FIELD-B USAGE BINARY-CHAR VALUE 2. + 05 INNER-GROUP. + 10 FIELD-C USAGE COMP-1 VALUE 3. + 05 FIELD-D PIC X VALUE "A". + 01 GROUP-2. + 05 FIELD-A PIC 9. + 05 FIELD-B USAGE BINARY-LONG. + 05 INNER-GROUP. + 10 FIELD-C PIC 9. + 05 FIELD-D PIC 9. + + PROCEDURE DIVISION. + ADD CORRESPONDING GROUP-1 TO GROUP-2. + IF FIELD-A IN GROUP-2 NOT EQUAL 1 THEN + DISPLAY "BAD FIELD-A " FIELD-A IN GROUP-2 + END-DISPLAY + END-IF. + IF FIELD-B IN GROUP-2 NOT EQUAL 2 THEN + DISPLAY "BAD FIELD-B " FIELD-B IN GROUP-2 + END-DISPLAY + END-IF. + IF FIELD-C IN GROUP-2 NOT EQUAL 3 THEN + DISPLAY "BAD FIELD-C " FIELD-C IN GROUP-2 + END-DISPLAY + END-IF. + IF FIELD-D IN GROUP-2 NOT EQUAL 0 THEN + DISPLAY "BAD FIELD-D " FIELD-D IN GROUP-2 + END-DISPLAY + END-IF. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ADD_SUBTRACT_CORR_mixed_fix___float.cob b/gcc/testsuite/cobol.dg/group2/ADD_SUBTRACT_CORR_mixed_fix___float.cob new file mode 100644 index 0000000..d90ab7b --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ADD_SUBTRACT_CORR_mixed_fix___float.cob @@ -0,0 +1,33 @@ + *> { dg-do run } + *> { dg-output-file "group2/ADD_SUBTRACT_CORR_mixed_fix___float.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 GROUP1. + 05 VAR1 PIC 9999 VALUE 1. + 05 VAR2 PIC 9999 VALUE 2. + 05 VAR3 COMP-2 VALUE 3. + 05 VAR4 COMP-2 VALUE 4. + 01 GROUP2. + 05 VAR1 PIC 9999 VALUE 1000. + 05 VAR2 COMP-2 VALUE 2000. + 05 VAR3 PIC 9999 VALUE 3000. + 05 VAR4 COMP-2 VALUE 4000. + PROCEDURE DIVISION. + PERFORM DISP2 + ADD CORRESPONDING GROUP1 TO GROUP2 + PERFORM DISP2 + SUBTRACT CORRESPONDING GROUP1 FROM GROUP2 + PERFORM DISP2. + GOBACK. + DISP2. + DISPLAY + VAR1 OF GROUP2 SPACE + VAR2 OF GROUP2 SPACE + VAR3 OF GROUP2 SPACE + VAR4 OF GROUP2. + END PROGRAM prog. + + diff --git a/gcc/testsuite/cobol.dg/group2/ADD_SUBTRACT_CORR_mixed_fix___float.out b/gcc/testsuite/cobol.dg/group2/ADD_SUBTRACT_CORR_mixed_fix___float.out new file mode 100644 index 0000000..e590ce3 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ADD_SUBTRACT_CORR_mixed_fix___float.out @@ -0,0 +1,4 @@ +1000 2000 3000 4000 +1001 2002 3003 4004 +1000 2000 3000 4000 + diff --git a/gcc/testsuite/cobol.dg/group2/ALPHABETIC-LOWER_test.cob b/gcc/testsuite/cobol.dg/group2/ALPHABETIC-LOWER_test.cob new file mode 100644 index 0000000..ff71974 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ALPHABETIC-LOWER_test.cob @@ -0,0 +1,23 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(04) VALUE "aaaa". + 01 FILLER REDEFINES X. + 03 XBYTE PIC X. + 03 FILLER PIC XXX. + PROCEDURE DIVISION. + MOVE X"0D" TO XBYTE. + IF X ALPHABETIC-LOWER + DISPLAY "Fail - Not alphabetic lower" + END-DISPLAY + END-IF. + MOVE "a" TO XBYTE. + IF X NOT ALPHABETIC-LOWER + DISPLAY "Fail - Alphabetic lower" + END-DISPLAY + END-IF. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ALPHABETIC-UPPER_test.cob b/gcc/testsuite/cobol.dg/group2/ALPHABETIC-UPPER_test.cob new file mode 100644 index 0000000..a3c7ed8 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ALPHABETIC-UPPER_test.cob @@ -0,0 +1,23 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(04) VALUE "AAAA". + 01 FILLER REDEFINES X. + 03 XBYTE PIC X. + 03 FILLER PIC XXX. + PROCEDURE DIVISION. + MOVE X"0D" TO XBYTE. + IF X ALPHABETIC-UPPER + DISPLAY "Fail - Not alphabetic upper" + END-DISPLAY + END-IF. + MOVE "A" TO XBYTE. + IF X NOT ALPHABETIC-UPPER + DISPLAY "Fail - Alphabetic upper" + END-DISPLAY + END-IF. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ALPHABETIC_test.cob b/gcc/testsuite/cobol.dg/group2/ALPHABETIC_test.cob new file mode 100644 index 0000000..ebc38cc --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ALPHABETIC_test.cob @@ -0,0 +1,23 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(04) VALUE "AAAA". + 01 FILLER REDEFINES X. + 03 XBYTE PIC X. + 03 FILLER PIC XXX. + PROCEDURE DIVISION. + MOVE X"0D" TO XBYTE. + IF X ALPHABETIC + DISPLAY "Fail - Alphabetic" + END-DISPLAY + END-IF. + MOVE "A" TO XBYTE. + IF X NOT ALPHABETIC + DISPLAY "Fail - Not Alphabetic" + END-DISPLAY + END-IF. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/BLANK_WHEN_ZERO.cob b/gcc/testsuite/cobol.dg/group2/BLANK_WHEN_ZERO.cob new file mode 100644 index 0000000..ae0aa71 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/BLANK_WHEN_ZERO.cob @@ -0,0 +1,16 @@ + *> { dg-do run } + *> { dg-output-file "group2/BLANK_WHEN_ZERO.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 x PIC 9, BLANK WHEN ZERO, VALUE 1. + PROCEDURE DIVISION. + DISPLAY "X should be 1: " """" x """" + MOVE 0 TO x + DISPLAY "X should be blank: " """" FUNCTION TRIM(x) """" + MOVE ZERO TO x + DISPLAY "X should be blank: " """" FUNCTION TRIM(x) """" + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/BLANK_WHEN_ZERO.out b/gcc/testsuite/cobol.dg/group2/BLANK_WHEN_ZERO.out new file mode 100644 index 0000000..a03f1d1 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/BLANK_WHEN_ZERO.out @@ -0,0 +1,4 @@ +X should be 1: "1" +X should be blank: "" +X should be blank: "" + diff --git a/gcc/testsuite/cobol.dg/group2/Check_for_equality_of_COMP-1___COMP-2.cob b/gcc/testsuite/cobol.dg/group2/Check_for_equality_of_COMP-1___COMP-2.cob new file mode 100644 index 0000000..76bafa4 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Check_for_equality_of_COMP-1___COMP-2.cob @@ -0,0 +1,106 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 SRC1 COMP-2 VALUE 11.55. + 01 DST1 COMP-1. + 01 SRC2 COMP-1 VALUE 11.55. + 01 DST2 COMP-2. + + PROCEDURE DIVISION. + MOVE SRC1 TO DST1. + IF DST1 not = 11.55 + DISPLAY 'error: move/compare FLOAT-LONG to FLOAT-SHORT failed ' DST1 + END-DISPLAY + END-IF. + + MOVE SRC1 TO DST2. + IF DST1 not = 11.55 + DISPLAY 'error: move/compare FLOAT-LONG to FLOAT-LONG failed ' DST2 + END-DISPLAY + END-IF. + + MOVE ZERO TO DST1. + MOVE ZERO TO DST2. + + MOVE SRC2 TO DST1. + IF DST1 not = 11.55 + DISPLAY 'error: move/compare FLOAT-SHORT to FLOAT-SHORT failed: ' DST1 + END-DISPLAY + END-IF. + + MOVE SRC2 TO DST2. + IF DST2 not = 11.5500001907348633 + DISPLAY 'error: move/compare COMP-2 to literal failed: ' DST2 + END-DISPLAY + END-IF. + + MOVE ZERO TO DST1. + IF not (DST1 = 0 AND 0.0) + DISPLAY "Zero compare failed: " DST1 END-DISPLAY + END-IF. + + MOVE -0.0 TO DST1. + IF not (DST1 = 0 AND 0.0) + DISPLAY "Negative Zero compare failed: " DST1 + END-DISPLAY + END-IF. + + MOVE 1.1234567 TO DST1. + MOVE DST1 TO DST2. + IF DST2 not = 1.12345671653747559 + DISPLAY "move/compare number to FLOAT to DOUBLE failed: " + DST1 " - " DST2 + END-DISPLAY + END-IF. + + * Check for Tolerance + MOVE 1.1234567 TO DST1. + MOVE 1.1234568 TO DST2. + IF DST1 = DST2 THEN + DISPLAY 'move/compare of very near numbers failed (not identical): ' DST1 " - " DST2 + END-DISPLAY + END-IF. + + * Within tolerance by definition, therefore not checked + * MULTIPLY 10000000000 BY DST1 DST2 END-MULTIPLY. + * IF DST1 = DST2 THEN + * DISPLAY "compare of very near numbers computed failed (id + *- "entical): " DST1 " - " DST2 + * END-DISPLAY + * END-IF. + + MOVE 1.1234567 TO DST1. + MOVE 1.1234569 TO DST2. + IF DST1 = DST2 THEN + DISPLAY 'move/compare of near equal numbers failed (identical): ' DST1 " - " DST2 + END-DISPLAY + END-IF. + + MOVE 0.0001 TO DST1. + MOVE 0.0000 TO DST2. + IF DST1 = DST2 THEN + DISPLAY 'move/compare of nearly equal very small numbers failed (identical): ' DST1 " - " DST2 + END-DISPLAY + END-IF. + + MOVE 1000001.0 TO DST1. + MOVE 1000000.0 TO DST2. + IF DST1 = DST2 THEN + DISPLAY 'move/compare of nearly equal big numbers failed (identical): ' DST1 " - " DST2 + END-DISPLAY + END-IF. + + * Within tolerance by definition, therefore not checked + * MOVE 1000000000.0 TO DST1. + * MOVE 1000000001.0 TO DST2. + * IF DST1 = DST2 THEN + * DISPLAY 'move/compare of nearly equal very big numbers fa + *- 'iled (identical): ' DST1 " - " DST2 + * END-DISPLAY + * END-IF. + + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Compare_COMP-2_with_floating-point_literal.cob b/gcc/testsuite/cobol.dg/group2/Compare_COMP-2_with_floating-point_literal.cob new file mode 100644 index 0000000..677fadc --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Compare_COMP-2_with_floating-point_literal.cob @@ -0,0 +1,43 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 VAR COMP-2 VALUE 0.0. + + PROCEDURE DIVISION. + MOVE 9.899999999999E+304 TO VAR + IF VAR < 0 + DISPLAY "error: compare " VAR " < " 0 " failed!" + END-DISPLAY + END-IF. + IF VAR < 9.799999999999E+304 + DISPLAY 'error: compare ' VAR ' < ' 9.799999999999E+304 + ' failed!' + END-DISPLAY + END-IF. + IF VAR > 9.999999999999E+304 + DISPLAY 'error: compare ' VAR ' > ' 9.999999999999E+304 + ' failed!' + END-DISPLAY + END-IF. + MOVE -9.899999999999E+304 TO VAR + IF VAR > 0 + DISPLAY 'error: compare ' VAR ' > ' 0 + ' failed!' + END-DISPLAY + END-IF. + IF VAR < -9.999999999999E+304 + DISPLAY 'error: compare ' VAR ' < ' -9.999999999999E+304 + ' failed!' + END-DISPLAY + END-IF. + IF VAR > -9.799999999999E+304 + DISPLAY 'error: compare ' VAR ' > ' -9.799999999999E+304 + ' failed!' + END-DISPLAY + END-IF. + + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__3_.cob b/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__3_.cob new file mode 100644 index 0000000..624a9e1 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__3_.cob @@ -0,0 +1,42 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(5) GLOBAL VALUE "prog1". + PROCEDURE DIVISION. + IF X NOT = "prog1" + DISPLAY X + END-DISPLAY + END-IF. + CALL "prog2" + END-CALL. + STOP RUN. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(5) GLOBAL VALUE "prog2". + PROCEDURE DIVISION. + IF X NOT = "prog2" + DISPLAY X + END-DISPLAY + END-IF. + CALL "prog3" + END-CALL. + EXIT PROGRAM. + END PROGRAM prog2. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog3 COMMON. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + IF X NOT = "prog1" + DISPLAY X + END-DISPLAY + END-IF. + EXIT PROGRAM. + END PROGRAM prog3. + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__4_.cob b/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__4_.cob new file mode 100644 index 0000000..923ce76 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__4_.cob @@ -0,0 +1,46 @@ + *> { dg-do run } + *> { dg-output-file "group2/Contained_program_visibility__4_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY "P1" NO ADVANCING + END-DISPLAY. + CALL "prog2" + END-CALL + CALL "prog3" + END-CALL + STOP RUN. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY "P2" NO ADVANCING + END-DISPLAY. + EXIT PROGRAM. + END PROGRAM prog2. + END PROGRAM prog. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog3. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY "P3" NO ADVANCING + END-DISPLAY. + CALL "prog2" + END-CALL. + EXIT PROGRAM. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY "P4" NO ADVANCING + END-DISPLAY. + EXIT PROGRAM. + END PROGRAM prog2. + END PROGRAM prog3. + diff --git a/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__4_.out b/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__4_.out new file mode 100644 index 0000000..f31c96b --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Contained_program_visibility__4_.out @@ -0,0 +1 @@ +P1P2P3P4 diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__1_.cob b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__1_.cob new file mode 100644 index 0000000..37f5c47 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__1_.cob @@ -0,0 +1,15 @@ + *> { dg-do run } + *> { dg-output-file "group2/Context_sensitive_words__1_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 BYTE-LENGTH PIC 9. + 01 X CONSTANT AS BYTE-LENGTH OF BYTE-LENGTH. + PROCEDURE DIVISION. + MOVE X TO BYTE-LENGTH. + DISPLAY BYTE-LENGTH NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__1_.out b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__1_.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__1_.out @@ -0,0 +1 @@ +1 diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__2_.cob b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__2_.cob new file mode 100644 index 0000000..d29f505 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__2_.cob @@ -0,0 +1,16 @@ + *> { dg-do run } + *> { dg-output-file "group2/Context_sensitive_words__2_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 YYYYMMDD PIC 9 VALUE 0. + 01 X PIC X(16). + PROCEDURE DIVISION. + ACCEPT X FROM DATE YYYYMMDD + END-ACCEPT. + DISPLAY YYYYMMDD NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__2_.out b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__2_.out new file mode 100644 index 0000000..573541a --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__2_.out @@ -0,0 +1 @@ +0 diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__3_.cob b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__3_.cob new file mode 100644 index 0000000..0326650 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__3_.cob @@ -0,0 +1,16 @@ + *> { dg-do run } + *> { dg-output-file "group2/Context_sensitive_words__3_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 YYYYDDD PIC 9 VALUE 0. + 01 X PIC X(16). + PROCEDURE DIVISION. + ACCEPT X FROM DAY YYYYDDD + END-ACCEPT. + DISPLAY YYYYDDD NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__3_.out b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__3_.out new file mode 100644 index 0000000..573541a --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__3_.out @@ -0,0 +1 @@ +0 diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__4_.cob b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__4_.cob new file mode 100644 index 0000000..05f2197 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__4_.cob @@ -0,0 +1,17 @@ + *> { dg-do run } + *> { dg-output-file "group2/Context_sensitive_words__4_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + REPOSITORY. + FUNCTION ALL INTRINSIC. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 INTRINSIC PIC 9 VALUE 0. + PROCEDURE DIVISION. + DISPLAY INTRINSIC NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__4_.out b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__4_.out new file mode 100644 index 0000000..573541a --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__4_.out @@ -0,0 +1 @@ +0 diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__5_.cob b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__5_.cob new file mode 100644 index 0000000..8a96cf1 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__5_.cob @@ -0,0 +1,15 @@ + *> { dg-do run } + *> { dg-output-file "group2/Context_sensitive_words__5_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog RECURSIVE. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 RECURSIVE PIC 9 VALUE 0. + PROCEDURE DIVISION. + DISPLAY RECURSIVE NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__5_.out b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__5_.out new file mode 100644 index 0000000..573541a --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__5_.out @@ -0,0 +1 @@ +0 diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__6_.cob b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__6_.cob new file mode 100644 index 0000000..f83cb63 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__6_.cob @@ -0,0 +1,14 @@ + *> { dg-do run } + *> { dg-output-file "group2/Context_sensitive_words__6_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 NORMAL PIC 9 VALUE 0. + PROCEDURE DIVISION. + DISPLAY NORMAL NO ADVANCING *> Intentionally no period or END-DISPLAY + STOP RUN NORMAL. + diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__6_.out b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__6_.out new file mode 100644 index 0000000..573541a --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__6_.out @@ -0,0 +1 @@ +0 diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__7_.cob b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__7_.cob new file mode 100644 index 0000000..0ad5cc8 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__7_.cob @@ -0,0 +1,19 @@ + *> { dg-do run } + *> { dg-output-file "group2/Context_sensitive_words__7_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC 9 VALUE 0. + 01 AWAY-FROM-ZERO PIC 9 VALUE 0. + PROCEDURE DIVISION. + COMPUTE X ROUNDED MODE AWAY-FROM-ZERO + AWAY-FROM-ZERO = 1.1 + END-COMPUTE + DISPLAY X AWAY-FROM-ZERO NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__7_.out b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__7_.out new file mode 100644 index 0000000..aabe6ec --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__7_.out @@ -0,0 +1 @@ +21 diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__8_.cob b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__8_.cob new file mode 100644 index 0000000..8943f92 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__8_.cob @@ -0,0 +1,19 @@ + *> { dg-do run } + *> { dg-output-file "group2/Context_sensitive_words__8_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 UNBNDED. + 03 ATTRIBUTES PIC 9 VALUE 0. + 01 LOC. + 03 NAMESPACE PIC 9 VALUE 1. + PROCEDURE DIVISION. + DISPLAY UNBNDED ATTRIBUTES + NAMESPACE IN LOC + NO ADVANCING. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__8_.out b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__8_.out new file mode 100644 index 0000000..5325a8d --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Context_sensitive_words__8_.out @@ -0,0 +1 @@ +001 diff --git a/gcc/testsuite/cobol.dg/group2/DEBUG_Line.cob b/gcc/testsuite/cobol.dg/group2/DEBUG_Line.cob new file mode 100644 index 0000000..a7dca5d --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DEBUG_Line.cob @@ -0,0 +1,16 @@ + *> { dg-do run } + *> { dg-output-file "group2/DEBUG_Line.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + SOURCE-COMPUTER. + Linux WITH DEBUGGING MODE. + PROCEDURE DIVISION. + *> Success is printing this message. If nothing comes out, the + *> test fails. + D DISPLAY "DEBUG MESSAGE" NO ADVANCING. + EXIT PROGRAM. + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/DEBUG_Line.out b/gcc/testsuite/cobol.dg/group2/DEBUG_Line.out new file mode 100644 index 0000000..6a3f59c --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DEBUG_Line.out @@ -0,0 +1 @@ +DEBUG MESSAGE diff --git a/gcc/testsuite/cobol.dg/group2/DISPLAY_and_assignment_NumericDisplay.cob b/gcc/testsuite/cobol.dg/group2/DISPLAY_and_assignment_NumericDisplay.cob new file mode 100644 index 0000000..2b31113 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DISPLAY_and_assignment_NumericDisplay.cob @@ -0,0 +1,82 @@ + *> { dg-do run } + *> { dg-output-file "group2/DISPLAY_and_assignment_NumericDisplay.out" } + identification division. + program-id. prog. + data division. + working-storage section. + 01 vars. + 05 vars-display-1. + 10 var01a pic 99v999 display value 54.321 . + 10 var01b pic s99v999 display value 54.321 . + 10 var01c pic s99v999 leading display value -54.321 . + 10 var01d pic s99v999 trailing display value 54.321 . + 10 var01e pic s99v999 leading separate display value -54.321 . + 10 var01f pic s99v999 trailing separate display value 54.321 . + 05 vars-display-2. + 10 var01g pic 9999ppp display value 4321000 . + 10 var01h pic s9999ppp display value 4321000 . + 10 var01i pic s9999ppp leading display value -4321000 . + 10 var01j pic s9999ppp trailing display value 4321000 . + 10 var01k pic s9999ppp leading separate display value -4321000 . + 10 var01l pic s9999ppp trailing separate display value 4321000 . + 05 vars-display-3. + 10 var01m pic ppp9999 display value .0001234 . + 10 var01n pic sppp9999 display value .0001234 . + 10 var01o pic sppp9999 leading display value -.0001234 . + 10 var01p pic sppp9999 trailing display value .0001234 . + 10 var01q pic sppp9999 leading separate display value -.0001234 . + 10 var01r pic sppp9999 trailing separate display value .0001234 . + procedure division. + display var01a + display var01b + display var01c + display var01d + display var01e + display var01f + display var01g + display var01h + display var01i + display var01j + display var01k + display var01l + display var01m + display var01n + display var01o + display var01p + display var01q + display var01r + + move 12.345 to var01a var01c var01e + move -12.345 to var01b var01d var01f + + move 9876000 to var01g var01i var01k + move -9876000 to var01h var01j var01l + + move .0006789 to var01m var01o var01q + move -.0006789 to var01n var01p var01r + + display var01a + display var01b + display var01c + display var01d + display var01e + display var01f + display var01g + display var01h + display var01i + display var01j + display var01k + display var01l + display var01m + display var01n + display var01o + display var01p + display var01q + display var01r + + continue. + quit. + goback. + end program prog. + + diff --git a/gcc/testsuite/cobol.dg/group2/DISPLAY_and_assignment_NumericDisplay.out b/gcc/testsuite/cobol.dg/group2/DISPLAY_and_assignment_NumericDisplay.out new file mode 100644 index 0000000..b18b32d --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DISPLAY_and_assignment_NumericDisplay.out @@ -0,0 +1,37 @@ +54.321 ++54.321 +-54.321 ++54.321 +-54.321 +54.321+ +4321000 ++4321000 +-4321000 ++4321000 +-4321000 +4321000+ +.0001234 ++.0001234 +-.0001234 ++.0001234 +-.0001234 +.0001234+ +12.345 +-12.345 ++12.345 +-12.345 ++12.345 +12.345- +9876000 +-9876000 ++9876000 +-9876000 ++9876000 +9876000- +.0006789 +-.0006789 ++.0006789 +-.0006789 ++.0006789 +.0006789- + diff --git a/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_MOVE_statement.cob b/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_MOVE_statement.cob new file mode 100644 index 0000000..50c1391 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_MOVE_statement.cob @@ -0,0 +1,38 @@ + *> { dg-do run } + *> { dg-output-file "group2/DISPLAY_data_items_with_MOVE_statement.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X-ABC PIC XXX VALUE "abc". + 01 X-123 PIC 999 VALUE 123. + 01 X-P123 PIC S999 VALUE +123. + 01 X-N123 PIC S999 VALUE -123. + 01 X-12-3 PIC 99V9 VALUE 12.3. + 01 X-P12-3 PIC S99V9 VALUE +12.3. + 01 X-N12-3 PIC S99V9 VALUE -12.3. + PROCEDURE DIVISION. + MOVE "abc" TO X-ABC. + DISPLAY X-ABC + END-DISPLAY. + MOVE 123 TO X-123. + DISPLAY X-123 + END-DISPLAY. + MOVE +123 TO X-P123. + DISPLAY X-P123 + END-DISPLAY. + MOVE -123 TO X-N123. + DISPLAY X-N123 + END-DISPLAY. + MOVE 12.3 TO X-12-3. + DISPLAY X-12-3 + END-DISPLAY. + MOVE +12.3 TO X-P12-3. + DISPLAY X-P12-3 + END-DISPLAY. + MOVE -12.3 TO X-N12-3. + DISPLAY X-N12-3 + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_MOVE_statement.out b/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_MOVE_statement.out new file mode 100644 index 0000000..e0624a9 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_MOVE_statement.out @@ -0,0 +1,8 @@ +abc +123 ++123 +-123 +12.3 ++12.3 +-12.3 + diff --git a/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_VALUE_clause.cob b/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_VALUE_clause.cob new file mode 100644 index 0000000..6e502cb --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_VALUE_clause.cob @@ -0,0 +1,31 @@ + *> { dg-do run } + *> { dg-output-file "group2/DISPLAY_data_items_with_VALUE_clause.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X-ABC PIC XXX VALUE "abc". + 01 X-123 PIC 999 VALUE 123. + 01 X-P123 PIC S999 VALUE +123. + 01 X-N123 PIC S999 VALUE -123. + 01 X-12-3 PIC 99V9 VALUE 12.3. + 01 X-P12-3 PIC S99V9 VALUE +12.3. + 01 X-N12-3 PIC S99V9 VALUE -12.3. + PROCEDURE DIVISION. + DISPLAY X-ABC + END-DISPLAY. + DISPLAY X-123 + END-DISPLAY. + DISPLAY X-P123 + END-DISPLAY. + DISPLAY X-N123 + END-DISPLAY. + DISPLAY X-12-3 + END-DISPLAY. + DISPLAY X-P12-3 + END-DISPLAY. + DISPLAY X-N12-3 + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_VALUE_clause.out b/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_VALUE_clause.out new file mode 100644 index 0000000..e0624a9 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_VALUE_clause.out @@ -0,0 +1,8 @@ +abc +123 ++123 +-123 +12.3 ++12.3 +-12.3 + diff --git a/gcc/testsuite/cobol.dg/group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.cob b/gcc/testsuite/cobol.dg/group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.cob new file mode 100644 index 0000000..8bb5a58 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.cob @@ -0,0 +1,24 @@ + *> { dg-do run } + *> { dg-output-file "group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + SPECIAL-NAMES. + DECIMAL-POINT IS COMMA. + PROCEDURE DIVISION. + DISPLAY 12,3 + END-DISPLAY. + DISPLAY +12,3 + END-DISPLAY. + DISPLAY -12,3 + END-DISPLAY. + DISPLAY 1,23E0 + END-DISPLAY. + DISPLAY +1,23E0 + END-DISPLAY. + DISPLAY -1,23E0 + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.out b/gcc/testsuite/cobol.dg/group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.out new file mode 100644 index 0000000..4f56ca9 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.out @@ -0,0 +1,7 @@ +12,3 +12,3 +-12,3 +1,23 +1,23 +-1,23 + diff --git a/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__1_.cob b/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__1_.cob new file mode 100644 index 0000000..6d89908 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__1_.cob @@ -0,0 +1,42 @@ + *> { dg-do compile } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT TEST-FILE + ASSIGN "TESTFILE" + ACCESS DYNAMIC + ORGANIZATION RELATIVE + STATUS TESTSTAT + RELATIVE KEY TESTKEY + . + DATA DIVISION. + FILE SECTION. + FD TEST-FILE GLOBAL. + 01 TEST-REC PIC X(4). + WORKING-STORAGE SECTION. + 01 GLOBVALS. + 03 TESTKEY PIC 9(4). + 03 TESTSTAT PIC XX. + PROCEDURE DIVISION. + OPEN INPUT TEST-FILE. + CALL "prog2" + END-CALL. + CLOSE TEST-FILE. + STOP RUN. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + READ TEST-FILE + INVALID KEY + DISPLAY "NOK" + END-DISPLAY + END-READ. + EXIT PROGRAM. + END PROGRAM prog2. + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__2_.cob b/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__2_.cob new file mode 100644 index 0000000..44d5b2e --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__2_.cob @@ -0,0 +1,42 @@ + *> { dg-do compile } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT TEST-FILE + ASSIGN "TESTFILE" + ACCESS DYNAMIC + ORGANIZATION INDEXED + STATUS TESTSTAT + RECORD KEY TESTKEY + . + DATA DIVISION. + FILE SECTION. + FD TEST-FILE GLOBAL. + 01 TEST-REC. + 03 TESTKEY PIC X(4). + WORKING-STORAGE SECTION. + 01 GLOBVALS. + 03 TESTSTAT PIC XX. + PROCEDURE DIVISION. + OPEN INPUT TEST-FILE. + CALL "prog2" + END-CALL. + CLOSE TEST-FILE. + STOP RUN. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + READ TEST-FILE + INVALID KEY + DISPLAY "NOK" + END-DISPLAY + END-READ. + EXIT PROGRAM. + END PROGRAM prog2. + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__3_.cob b/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__3_.cob new file mode 100644 index 0000000..0f423babd --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__3_.cob @@ -0,0 +1,41 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT TEST-FILE + ASSIGN "TESTFILE" + ACCESS DYNAMIC + ORGANIZATION RELATIVE + STATUS TESTSTAT + RELATIVE KEY TESTKEY + . + DATA DIVISION. + FILE SECTION. + FD TEST-FILE GLOBAL. + 01 TEST-REC PIC X(4). + WORKING-STORAGE SECTION. + 01 GLOBVALS. + 03 TESTKEY PIC 9(4). + 03 TESTSTAT PIC XX. + PROCEDURE DIVISION. + MOVE "00" TO TESTSTAT. + CALL "prog2" + END-CALL. + IF TESTSTAT = "00" + DISPLAY "Not OK" + END-DISPLAY + END-IF. + STOP RUN. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + OPEN INPUT TEST-FILE. + EXIT PROGRAM. + END PROGRAM prog2. + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__4_.cob b/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__4_.cob new file mode 100644 index 0000000..116a935 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/GLOBAL_FD__4_.cob @@ -0,0 +1,41 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT TEST-FILE + ASSIGN "TESTFILE" + ACCESS DYNAMIC + ORGANIZATION INDEXED + STATUS TESTSTAT + RECORD KEY TESTKEY + . + DATA DIVISION. + FILE SECTION. + FD TEST-FILE GLOBAL. + 01 TEST-REC. + 03 TESTKEY PIC X(4). + WORKING-STORAGE SECTION. + 01 GLOBVALS. + 03 TESTSTAT PIC XX. + PROCEDURE DIVISION. + MOVE "00" TO TESTSTAT. + CALL "prog2" + END-CALL. + IF TESTSTAT = "00" + DISPLAY "Not OK" + END-DISPLAY + END-IF. + STOP RUN. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + OPEN INPUT TEST-FILE. + EXIT PROGRAM. + END PROGRAM prog2. + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/GLOBAL_at_lower_level.cob b/gcc/testsuite/cobol.dg/group2/GLOBAL_at_lower_level.cob new file mode 100644 index 0000000..f4b5cba --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/GLOBAL_at_lower_level.cob @@ -0,0 +1,37 @@ + *> { dg-do run } + *> { dg-output-file "group2/GLOBAL_at_lower_level.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(5) GLOBAL VALUE "prog1". + PROCEDURE DIVISION. + DISPLAY X + END-DISPLAY. + CALL "prog2" + END-CALL + STOP RUN. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(5) GLOBAL VALUE "prog2". + PROCEDURE DIVISION. + DISPLAY X + END-DISPLAY. + CALL "prog3" + END-CALL + EXIT PROGRAM. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog3. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY X + END-DISPLAY. + EXIT PROGRAM. + END PROGRAM prog3. + END PROGRAM prog2. + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/GLOBAL_at_lower_level.out b/gcc/testsuite/cobol.dg/group2/GLOBAL_at_lower_level.out new file mode 100644 index 0000000..ab69cb1 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/GLOBAL_at_lower_level.out @@ -0,0 +1,4 @@ +prog1 +prog2 +prog2 + diff --git a/gcc/testsuite/cobol.dg/group2/GLOBAL_at_same_level.cob b/gcc/testsuite/cobol.dg/group2/GLOBAL_at_same_level.cob new file mode 100644 index 0000000..749a26c --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/GLOBAL_at_same_level.cob @@ -0,0 +1,37 @@ + *> { dg-do run } + *> { dg-output-file "group2/GLOBAL_at_same_level.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(5) GLOBAL VALUE "prog1". + PROCEDURE DIVISION. + DISPLAY X + END-DISPLAY. + CALL "prog2" + END-CALL + CALL "prog3" + END-CALL + STOP RUN. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog2. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC X(5) GLOBAL VALUE "prog2". + PROCEDURE DIVISION. + DISPLAY X + END-DISPLAY. + EXIT PROGRAM. + END PROGRAM prog2. + IDENTIFICATION DIVISION. + PROGRAM-ID. prog3. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY X + END-DISPLAY. + EXIT PROGRAM. + END PROGRAM prog3. + END PROGRAM prog. + diff --git a/gcc/testsuite/cobol.dg/group2/GLOBAL_at_same_level.out b/gcc/testsuite/cobol.dg/group2/GLOBAL_at_same_level.out new file mode 100644 index 0000000..4bc5d8b --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/GLOBAL_at_same_level.out @@ -0,0 +1,4 @@ +prog1 +prog2 +prog1 + diff --git a/gcc/testsuite/cobol.dg/group2/Hexadecimal_literal.cob b/gcc/testsuite/cobol.dg/group2/Hexadecimal_literal.cob new file mode 100644 index 0000000..9722ebd --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Hexadecimal_literal.cob @@ -0,0 +1,15 @@ + *> { dg-do run } + *> { dg-output-file "group2/Hexadecimal_literal.out" } + + >>DEFINE CHARSET AS 'ASCII' + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + PROCEDURE DIVISION. + >>IF CHARSET = 'EBCDIC' + DISPLAY X"F1F2F3" + >>ELSE + DISPLAY X"313233" + >>END-IF + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Hexadecimal_literal.out b/gcc/testsuite/cobol.dg/group2/Hexadecimal_literal.out new file mode 100644 index 0000000..cc12087 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Hexadecimal_literal.out @@ -0,0 +1,2 @@ +123 + diff --git a/gcc/testsuite/cobol.dg/group2/MULTIPLY_BY_literal_in_INITIAL_program.cob b/gcc/testsuite/cobol.dg/group2/MULTIPLY_BY_literal_in_INITIAL_program.cob new file mode 100644 index 0000000..56f4703 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/MULTIPLY_BY_literal_in_INITIAL_program.cob @@ -0,0 +1,15 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog INITIAL. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 num PIC 9(4) VALUE 5. + 01 result PIC 9(4). + 01 ws-temp PIC 9(8)V99. + 01 ws-temp2 PIC 9(3)V99 VALUE 10.50. + PROCEDURE DIVISION. + MULTIPLY num BY 4 GIVING result + MOVE 1.10 TO WS-TEMP. + MULTIPLY WS-TEMP2 BY WS-TEMP GIVING WS-TEMP. + diff --git a/gcc/testsuite/cobol.dg/group2/Named_conditionals_-_fixed__float__and_alphabetic.cob b/gcc/testsuite/cobol.dg/group2/Named_conditionals_-_fixed__float__and_alphabetic.cob new file mode 100644 index 0000000..92a6511 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Named_conditionals_-_fixed__float__and_alphabetic.cob @@ -0,0 +1,69 @@ + *> { dg-do run } + *> { dg-output-file "group2/Named_conditionals_-_fixed__float__and_alphabetic.out" } + identification division. + program-id. prog. + data division. + working-storage section. + 01 makeofcar pic x(10). + 88 volksgroup value "skoda", "seat", + "audi", "volkswagen" + false "boat". + 88 germanmade value "volkswagen", "audi", + "mercedes", "bmw", + "porsche". + 01 agegroup pic 999. + 88 child value 0 through 12. + 88 teen value 13 through 19. + 88 adult value 20 through 999. + 01 floats float-long. + 88 neg value -1 through -.1 . + 88 zed value zero . + 88 pos value .1 through 1.0 . + procedure division. + move "ford" to makeofcar + display function trim (makeofcar) + if volksgroup display " volksgroup" end-if + if germanmade display " germanmade" end-if + move "skoda" to makeofcar + display function trim (makeofcar) + if volksgroup display " volksgroup" end-if + if germanmade display " germanmade" end-if + move "volkswagen" to makeofcar + display function trim (makeofcar) + if volksgroup display " volksgroup" end-if + if germanmade display " germanmade" end-if + move 5 to agegroup. + display agegroup with no advancing + if child display " child" end-if + if teen display " teen" end-if + if adult display " adult" end-if + move 15 to agegroup. + display agegroup with no advancing + if child display " child" end-if + if teen display " teen" end-if + if adult display " adult" end-if + move 75 to agegroup. + display agegroup with no advancing + if child display " child" end-if + if teen display " teen" end-if + if adult display " adult" end-if + move -0.5 to floats + display floats with no advancing + if neg display " minus" end-if + if zed display " zero" end-if + if pos display " plus" end-if + move zero to floats + display floats with no advancing + if neg display " minus" end-if + if zed display " zero" end-if + if pos display " plus" end-if + move 0.5 to floats + display floats with no advancing + if neg display " minus" end-if + if zed display " zero" end-if + if pos display " plus" end-if + continue. + quit. + goback. + end program prog. + diff --git a/gcc/testsuite/cobol.dg/group2/Named_conditionals_-_fixed__float__and_alphabetic.out b/gcc/testsuite/cobol.dg/group2/Named_conditionals_-_fixed__float__and_alphabetic.out new file mode 100644 index 0000000..9ac5e44 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Named_conditionals_-_fixed__float__and_alphabetic.out @@ -0,0 +1,13 @@ +ford +skoda + volksgroup +volkswagen + volksgroup + germanmade +005 child +015 teen +075 adult +-0.5 minus +0 zero +0.5 plus + diff --git a/gcc/testsuite/cobol.dg/group2/Numeric_operations__1_.cob b/gcc/testsuite/cobol.dg/group2/Numeric_operations__1_.cob new file mode 100644 index 0000000..1e8f48e --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Numeric_operations__1_.cob @@ -0,0 +1,35 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC S9V9. + 01 Y PIC S9V9 COMP-3. + PROCEDURE DIVISION. + MOVE -0.1 TO X. + ADD 1 TO X. + IF X NOT = 0.9 + DISPLAY X + END-DISPLAY + END-IF. + MOVE 0.1 TO X. + SUBTRACT 1 FROM X. + IF X NOT = -0.9 + DISPLAY X + END-DISPLAY + END-IF. + MOVE -0.1 TO Y. + ADD 1 TO Y. + IF Y NOT = 0.9 + DISPLAY Y + END-DISPLAY + END-IF. + MOVE 0.1 TO Y. + SUBTRACT 1 FROM Y. + IF Y NOT = -0.9 + DISPLAY Y + END-DISPLAY + END-IF. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Numeric_operations__2_.cob b/gcc/testsuite/cobol.dg/group2/Numeric_operations__2_.cob new file mode 100644 index 0000000..d7d71d7 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Numeric_operations__2_.cob @@ -0,0 +1,292 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FIELD PIC S9(1)V9(1). + 01 FELD2 PIC S9(5)V9(5). + 01 FELD3 PIC 9(1)V9(1). + 01 FELD4 PIC S9(1). + PROCEDURE DIVISION. + MOVE 0.2 TO FIELD + ADD 1 TO FIELD + IF FIELD NOT = 1.2 + DISPLAY "Test 1 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + ADD -1 TO FIELD + IF FIELD NOT = -0.8 + DISPLAY "Test 2 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + ADD 1 TO FIELD + IF FIELD NOT = 0.8 + DISPLAY "Test 3 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + ADD -1 TO FIELD + IF FIELD NOT = -1.2 + DISPLAY "Test 4 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + SUBTRACT 1 FROM FIELD + IF FIELD NOT = -0.8 + DISPLAY "Test 5 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + SUBTRACT -1 FROM FIELD + IF FIELD NOT = 1.2 + DISPLAY "Test 6 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + SUBTRACT 1 FROM FIELD + IF FIELD NOT = -1.2 + DISPLAY "Test 7 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + SUBTRACT -1 FROM FIELD + IF FIELD NOT = 0.8 + DISPLAY "Test 8 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + ADD 1 TO FELD2 + IF FELD2 NOT = 1.2 + DISPLAY "Test 9 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + ADD -1 TO FELD2 + IF FELD2 NOT = -0.8 + DISPLAY "Test 10 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + ADD 1 TO FELD2 + IF FELD2 NOT = 0.8 + DISPLAY "Test 11 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + ADD -1 TO FELD2 + IF FELD2 NOT = -1.2 + DISPLAY "Test 12 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + SUBTRACT 1 FROM FELD2 + IF FELD2 NOT = -0.8 + DISPLAY "Test 13 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + SUBTRACT -1 FROM FELD2 + IF FELD2 NOT = 1.2 + DISPLAY "Test 14 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + SUBTRACT 1 FROM FELD2 + IF FELD2 NOT = -1.2 + DISPLAY "Test 15 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + SUBTRACT -1 FROM FELD2 + IF FELD2 NOT = 0.8 + DISPLAY "Test 16 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + ADD 1 TO FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 17 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + ADD -1 TO FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 18 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + ADD 1 TO FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 19 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + ADD -1 TO FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 20 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + SUBTRACT 1 FROM FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 21 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + SUBTRACT -1 FROM FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 22 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + SUBTRACT 1 FROM FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 23 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + SUBTRACT -1 FROM FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 24 " FELD3 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + ADD 1 TO FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 25 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + ADD -1 TO FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 26 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + ADD 1 TO FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 27 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + ADD -1 TO FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 28 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + SUBTRACT 1 FROM FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 29 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + SUBTRACT -1 FROM FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 30 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + SUBTRACT 1 FROM FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 31 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + SUBTRACT -1 FROM FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 32 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + ADD 2 TO FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 33 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + ADD -2 TO FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 34 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + ADD 2 TO FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 35 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + ADD -2 TO FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 36 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + SUBTRACT 2 FROM FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 37 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + SUBTRACT -2 FROM FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 38 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + SUBTRACT 2 FROM FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 39 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + SUBTRACT -2 FROM FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 40 " FELD4 + END-DISPLAY + END-IF. + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/Numeric_operations__3_.cob b/gcc/testsuite/cobol.dg/group2/Numeric_operations__3_.cob new file mode 100644 index 0000000..e56804a --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Numeric_operations__3_.cob @@ -0,0 +1,292 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FIELD PIC S9(1)V9(1) COMP-3. + 01 FELD2 PIC S9(5)V9(5) COMP-3. + 01 FELD3 PIC 9(1)V9(1) COMP-3. + 01 FELD4 PIC S9(1) COMP-3. + PROCEDURE DIVISION. + MOVE 0.2 TO FIELD + ADD 1 TO FIELD + IF FIELD NOT = 1.2 + DISPLAY "Test 1 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + ADD -1 TO FIELD + IF FIELD NOT = -0.8 + DISPLAY "Test 2 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + ADD 1 TO FIELD + IF FIELD NOT = 0.8 + DISPLAY "Test 3 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + ADD -1 TO FIELD + IF FIELD NOT = -1.2 + DISPLAY "Test 4 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + SUBTRACT 1 FROM FIELD + IF FIELD NOT = -0.8 + DISPLAY "Test 5 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + SUBTRACT -1 FROM FIELD + IF FIELD NOT = 1.2 + DISPLAY "Test 6 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + SUBTRACT 1 FROM FIELD + IF FIELD NOT = -1.2 + DISPLAY "Test 7 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + SUBTRACT -1 FROM FIELD + IF FIELD NOT = 0.8 + DISPLAY "Test 8 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + ADD 1 TO FELD2 + IF FELD2 NOT = 1.2 + DISPLAY "Test 9 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + ADD -1 TO FELD2 + IF FELD2 NOT = -0.8 + DISPLAY "Test 10 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + ADD 1 TO FELD2 + IF FELD2 NOT = 0.8 + DISPLAY "Test 11 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + ADD -1 TO FELD2 + IF FELD2 NOT = -1.2 + DISPLAY "Test 12 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + SUBTRACT 1 FROM FELD2 + IF FELD2 NOT = -0.8 + DISPLAY "Test 13 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + SUBTRACT -1 FROM FELD2 + IF FELD2 NOT = 1.2 + DISPLAY "Test 14 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + SUBTRACT 1 FROM FELD2 + IF FELD2 NOT = -1.2 + DISPLAY "Test 15 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + SUBTRACT -1 FROM FELD2 + IF FELD2 NOT = 0.8 + DISPLAY "Test 16 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + ADD 1 TO FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 17 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + ADD -1 TO FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 18 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + ADD 1 TO FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 19 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + ADD -1 TO FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 20 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + SUBTRACT 1 FROM FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 21 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + SUBTRACT -1 FROM FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 22 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + SUBTRACT 1 FROM FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 23 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + SUBTRACT -1 FROM FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 24 " FELD3 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + ADD 1 TO FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 25 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + ADD -1 TO FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 26 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + ADD 1 TO FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 27 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + ADD -1 TO FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 28 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + SUBTRACT 1 FROM FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 29 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + SUBTRACT -1 FROM FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 30 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + SUBTRACT 1 FROM FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 31 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + SUBTRACT -1 FROM FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 32 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + ADD 2 TO FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 33 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + ADD -2 TO FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 34 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + ADD 2 TO FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 35 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + ADD -2 TO FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 36 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + SUBTRACT 2 FROM FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 37 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + SUBTRACT -2 FROM FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 38 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + SUBTRACT 2 FROM FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 39 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + SUBTRACT -2 FROM FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 40 " FELD4 + END-DISPLAY + END-IF. + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/Numeric_operations__4_.cob b/gcc/testsuite/cobol.dg/group2/Numeric_operations__4_.cob new file mode 100644 index 0000000..2b5c8ee --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Numeric_operations__4_.cob @@ -0,0 +1,292 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FIELD PIC S9(1)V9(1) COMP. + 01 FELD2 PIC S9(5)V9(5) COMP. + 01 FELD3 PIC 9(1)V9(1) COMP. + 01 FELD4 PIC S9(1) COMP. + PROCEDURE DIVISION. + MOVE 0.2 TO FIELD + ADD 1 TO FIELD + IF FIELD NOT = 1.2 + DISPLAY "Test 1 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + ADD -1 TO FIELD + IF FIELD NOT = -0.8 + DISPLAY "Test 2 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + ADD 1 TO FIELD + IF FIELD NOT = 0.8 + DISPLAY "Test 3 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + ADD -1 TO FIELD + IF FIELD NOT = -1.2 + DISPLAY "Test 4 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + SUBTRACT 1 FROM FIELD + IF FIELD NOT = -0.8 + DISPLAY "Test 5 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + SUBTRACT -1 FROM FIELD + IF FIELD NOT = 1.2 + DISPLAY "Test 6 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + SUBTRACT 1 FROM FIELD + IF FIELD NOT = -1.2 + DISPLAY "Test 7 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + SUBTRACT -1 FROM FIELD + IF FIELD NOT = 0.8 + DISPLAY "Test 8 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + ADD 1 TO FELD2 + IF FELD2 NOT = 1.2 + DISPLAY "Test 9 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + ADD -1 TO FELD2 + IF FELD2 NOT = -0.8 + DISPLAY "Test 10 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + ADD 1 TO FELD2 + IF FELD2 NOT = 0.8 + DISPLAY "Test 11 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + ADD -1 TO FELD2 + IF FELD2 NOT = -1.2 + DISPLAY "Test 12 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + SUBTRACT 1 FROM FELD2 + IF FELD2 NOT = -0.8 + DISPLAY "Test 13 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + SUBTRACT -1 FROM FELD2 + IF FELD2 NOT = 1.2 + DISPLAY "Test 14 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + SUBTRACT 1 FROM FELD2 + IF FELD2 NOT = -1.2 + DISPLAY "Test 15 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + SUBTRACT -1 FROM FELD2 + IF FELD2 NOT = 0.8 + DISPLAY "Test 16 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + ADD 1 TO FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 17 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + ADD -1 TO FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 18 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + ADD 1 TO FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 19 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + ADD -1 TO FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 20 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + SUBTRACT 1 FROM FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 21 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + SUBTRACT -1 FROM FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 22 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + SUBTRACT 1 FROM FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 23 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + SUBTRACT -1 FROM FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 24 " FELD3 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + ADD 1 TO FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 25 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + ADD -1 TO FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 26 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + ADD 1 TO FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 27 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + ADD -1 TO FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 28 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + SUBTRACT 1 FROM FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 29 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + SUBTRACT -1 FROM FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 30 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + SUBTRACT 1 FROM FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 31 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + SUBTRACT -1 FROM FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 32 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + ADD 2 TO FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 33 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + ADD -2 TO FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 34 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + ADD 2 TO FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 35 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + ADD -2 TO FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 36 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + SUBTRACT 2 FROM FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 37 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + SUBTRACT -2 FROM FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 38 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + SUBTRACT 2 FROM FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 39 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + SUBTRACT -2 FROM FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 40 " FELD4 + END-DISPLAY + END-IF. + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/Numeric_operations__5_.cob b/gcc/testsuite/cobol.dg/group2/Numeric_operations__5_.cob new file mode 100644 index 0000000..1f72e69 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Numeric_operations__5_.cob @@ -0,0 +1,292 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FIELD PIC S9(1)V9(1) COMP-5. + 01 FELD2 PIC S9(5)V9(5) COMP-5. + 01 FELD3 PIC 9(1)V9(1) COMP-5. + 01 FELD4 PIC S9(1) COMP-5. + PROCEDURE DIVISION. + MOVE 0.2 TO FIELD + ADD 1 TO FIELD + IF FIELD NOT = 1.2 + DISPLAY "Test 1 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + ADD -1 TO FIELD + IF FIELD NOT = -0.8 + DISPLAY "Test 2 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + ADD 1 TO FIELD + IF FIELD NOT = 0.8 + DISPLAY "Test 3 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + ADD -1 TO FIELD + IF FIELD NOT = -1.2 + DISPLAY "Test 4 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + SUBTRACT 1 FROM FIELD + IF FIELD NOT = -0.8 + DISPLAY "Test 5 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FIELD + SUBTRACT -1 FROM FIELD + IF FIELD NOT = 1.2 + DISPLAY "Test 6 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + SUBTRACT 1 FROM FIELD + IF FIELD NOT = -1.2 + DISPLAY "Test 7 " FIELD + END-DISPLAY + END-IF. + + MOVE -0.2 TO FIELD + SUBTRACT -1 FROM FIELD + IF FIELD NOT = 0.8 + DISPLAY "Test 8 " FIELD + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + ADD 1 TO FELD2 + IF FELD2 NOT = 1.2 + DISPLAY "Test 9 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + ADD -1 TO FELD2 + IF FELD2 NOT = -0.8 + DISPLAY "Test 10 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + ADD 1 TO FELD2 + IF FELD2 NOT = 0.8 + DISPLAY "Test 11 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + ADD -1 TO FELD2 + IF FELD2 NOT = -1.2 + DISPLAY "Test 12 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + SUBTRACT 1 FROM FELD2 + IF FELD2 NOT = -0.8 + DISPLAY "Test 13 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD2 + SUBTRACT -1 FROM FELD2 + IF FELD2 NOT = 1.2 + DISPLAY "Test 14 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + SUBTRACT 1 FROM FELD2 + IF FELD2 NOT = -1.2 + DISPLAY "Test 15 " FELD2 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD2 + SUBTRACT -1 FROM FELD2 + IF FELD2 NOT = 0.8 + DISPLAY "Test 16 " FELD2 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + ADD 1 TO FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 17 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + ADD -1 TO FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 18 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + ADD 1 TO FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 19 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + ADD -1 TO FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 20 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + SUBTRACT 1 FROM FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 21 " FELD3 + END-DISPLAY + END-IF. + + MOVE 0.2 TO FELD3 + SUBTRACT -1 FROM FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 22 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + SUBTRACT 1 FROM FELD3 + IF FELD3 NOT = 0.8 + DISPLAY "Test 23 " FELD3 + END-DISPLAY + END-IF. + + MOVE -0.2 TO FELD3 + SUBTRACT -1 FROM FELD3 + IF FELD3 NOT = 1.2 + DISPLAY "Test 24 " FELD3 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + ADD 1 TO FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 25 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + ADD -1 TO FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 26 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + ADD 1 TO FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 27 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + ADD -1 TO FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 28 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + SUBTRACT 1 FROM FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 29 " FELD4 + END-DISPLAY + END-IF. + + MOVE 2 TO FELD4 + SUBTRACT -1 FROM FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 30 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + SUBTRACT 1 FROM FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 31 " FELD4 + END-DISPLAY + END-IF. + + MOVE -2 TO FELD4 + SUBTRACT -1 FROM FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 32 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + ADD 2 TO FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 33 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + ADD -2 TO FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 34 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + ADD 2 TO FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 35 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + ADD -2 TO FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 36 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + SUBTRACT 2 FROM FELD4 + IF FELD4 NOT = -1 + DISPLAY "Test 37 " FELD4 + END-DISPLAY + END-IF. + + MOVE 1 TO FELD4 + SUBTRACT -2 FROM FELD4 + IF FELD4 NOT = 3 + DISPLAY "Test 38 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + SUBTRACT 2 FROM FELD4 + IF FELD4 NOT = -3 + DISPLAY "Test 39 " FELD4 + END-DISPLAY + END-IF. + + MOVE -1 TO FELD4 + SUBTRACT -2 FROM FELD4 + IF FELD4 NOT = 1 + DISPLAY "Test 40 " FELD4 + END-DISPLAY + END-IF. + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/Numeric_operations__7_.cob b/gcc/testsuite/cobol.dg/group2/Numeric_operations__7_.cob new file mode 100644 index 0000000..df517db --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Numeric_operations__7_.cob @@ -0,0 +1,283 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 FIELD PIC S9(4)V9(2) COMP-5. + 01 FIELD-DISP PIC S9(4)V9(2) DISPLAY. + PROCEDURE DIVISION. + MOVE 0.2 TO FIELD. + ADD 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 + 120 + 121 + 122 + 123 + 124 + 125 + 126 + 127 + 128 + 129 + TO FIELD + END-ADD. + IF FIELD NOT = 8385.2 + MOVE FIELD TO FIELD-DISP + DISPLAY 'ADD with wrong result: ' FIELD-DISP + END-DISPLAY + END-IF. + COMPUTE FIELD = (0.2 + + 2 + + 3 + + 4 + + 5 + + 6 + + 7 + + 8 + + 9 + + 10 + + 11 + + 12 + + 13 + + 14 + + 15 + + 16 + + 17 + + 18 + + 19 + + 20 + + 21 + + 22 + + 23 + + 24 + + 25 + + 26 + + 27 + + 28 + + 29 + + 30 + + 31 + + 32 + + 33 + + 34 + + 35 + + 36 + + 37 + + 38 + + 39 + + 40 + + 41 + + 42 + + 43 + + 44 + + 45 + + 46 + + 47 + + 48 + + 49 + + 50 + + 51 + + 52 + + 53 + + 54 + + 55 + + 56 + + 57 + + 58 + - 59 + - 60 + - 61 + - 62 + - 63 + - 64 + - 65 + - 66 + - 67 + - 68 + - 69 + - 70 + - 71 + - 72 + - 73 + - 74 + - 75 + - 76 + - 77 + - 78 + - 79 + - 80 + - 81 + - 82 + - 83 + - 84 + - 85 + - 86 + - 87 + - 88 + - 89 + - 90 + - 91 + - 92 + - 93 + - 94 + - 95 + - 96 + - 97 + - 98 + - 99 + - 100 + - 101 + - 102 + - 103 + - 104 + - 105 + - 106 + - 107 + - 108 + - 109 + - 110 + - 111 + - 112 + - 113 + - 114 + - 115 + - 116 + - 117 + - 118 + - 119 + - 120 + - 121 + - 122 + - 123 + - 124 + - 125 + - 126 + - 127) + * 12800000000 + / 12900000000 + END-COMPUTE. + IF FIELD NOT = -4670.31 + MOVE FIELD TO FIELD-DISP + DISPLAY 'COMPUTE with wrong result: ' FIELD-DISP + END-DISPLAY + END-IF. + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/Numeric_operations__8_.cob b/gcc/testsuite/cobol.dg/group2/Numeric_operations__8_.cob new file mode 100644 index 0000000..68d5f9b --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Numeric_operations__8_.cob @@ -0,0 +1,37 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 1 COMPUTE-DATA. + 2 COMPUTE-8 PICTURE 999 VALUE ZERO. + PROCEDURE DIVISION. + COMPUTE COMPUTE-8 = (((24.0 + 1) * (60 - 10)) / 125) ** 2 + IF COMPUTE-8 NOT = 100 + DISPLAY 'COMPUTE with wrong result: ' COMPUTE-8 + END-DISPLAY + END-IF + COMPUTE COMPUTE-8 = 55 / (1 - 2 + 1) + NOT ON SIZE ERROR + DISPLAY 'SIZE ERROR not set from divide by zero!' + END-DISPLAY + END-COMPUTE + COMPUTE COMPUTE-8 = 0 ** 1 + IF COMPUTE-8 NOT = 0 + DISPLAY '0 ** 1 <> 0: ' COMPUTE-8 + END-DISPLAY + END-IF + COMPUTE COMPUTE-8 = 55 ** 0 + IF COMPUTE-8 NOT = 1 + DISPLAY '55 ** 0 <> 1: ' COMPUTE-8 + END-DISPLAY + END-IF + COMPUTE COMPUTE-8 = 1 ** 55 + IF COMPUTE-8 NOT = 1 + DISPLAY '11 ** 55 <> 1: ' COMPUTE-8 + END-DISPLAY + END-IF + + GOBACK. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_AWAY-FROM-ZERO.cob b/gcc/testsuite/cobol.dg/group2/ROUNDED_AWAY-FROM-ZERO.cob new file mode 100644 index 0000000..dc7ddad --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_AWAY-FROM-ZERO.cob @@ -0,0 +1,55 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDED_AWAY-FROM-ZERO.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 M PIC S9. + 01 N PIC S9. + 01 O PIC S9. + 01 P PIC S9. + 01 Q PIC S9. + 01 R PIC S9. + 01 S PIC S9. + 01 T PIC S9. + 01 U PIC S9. + 01 V PIC S9. + PROCEDURE DIVISION. + COMPUTE M ROUNDED MODE AWAY-FROM-ZERO + = 2.49 + END-COMPUTE + COMPUTE N ROUNDED MODE AWAY-FROM-ZERO + = -2.49 + END-COMPUTE + COMPUTE O ROUNDED MODE AWAY-FROM-ZERO + = 2.50 + END-COMPUTE + COMPUTE P ROUNDED MODE AWAY-FROM-ZERO + = -2.50 + END-COMPUTE + COMPUTE Q ROUNDED MODE AWAY-FROM-ZERO + = 3.49 + END-COMPUTE + COMPUTE R ROUNDED MODE AWAY-FROM-ZERO + = -3.49 + END-COMPUTE + COMPUTE S ROUNDED MODE AWAY-FROM-ZERO + = 3.50 + END-COMPUTE + COMPUTE T ROUNDED MODE AWAY-FROM-ZERO + = -3.50 + END-COMPUTE + COMPUTE U ROUNDED MODE AWAY-FROM-ZERO + = 3.510 + END-COMPUTE + COMPUTE V ROUNDED MODE AWAY-FROM-ZERO + = -3.510 + END-COMPUTE + DISPLAY M " " N " " O " " P " " Q " " R " " S " " T + " " U " " V + NO ADVANCING + END-DISPLAY + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_AWAY-FROM-ZERO.out b/gcc/testsuite/cobol.dg/group2/ROUNDED_AWAY-FROM-ZERO.out new file mode 100644 index 0000000..67784de --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_AWAY-FROM-ZERO.out @@ -0,0 +1 @@ ++3 -3 +3 -3 +4 -4 +4 -4 +4 -4 diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.cob b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.cob new file mode 100644 index 0000000..8a1e0ca --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.cob @@ -0,0 +1,55 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 M PIC S9. + 01 N PIC S9. + 01 O PIC S9. + 01 P PIC S9. + 01 Q PIC S9. + 01 R PIC S9. + 01 S PIC S9. + 01 T PIC S9. + 01 U PIC S9. + 01 V PIC S9. + PROCEDURE DIVISION. + COMPUTE M ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = 2.49 + END-COMPUTE + COMPUTE N ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = -2.49 + END-COMPUTE + COMPUTE O ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = 2.50 + END-COMPUTE + COMPUTE P ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = -2.50 + END-COMPUTE + COMPUTE Q ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = 3.49 + END-COMPUTE + COMPUTE R ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = -3.49 + END-COMPUTE + COMPUTE S ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = 3.50 + END-COMPUTE + COMPUTE T ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = -3.50 + END-COMPUTE + COMPUTE U ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = 3.510 + END-COMPUTE + COMPUTE V ROUNDED MODE NEAREST-AWAY-FROM-ZERO + = -3.510 + END-COMPUTE + DISPLAY M " " N " " O " " P " " Q " " R " " S " " T + " " U " " V + NO ADVANCING + END-DISPLAY + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.out b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.out new file mode 100644 index 0000000..18afa23 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.out @@ -0,0 +1 @@ ++2 -2 +3 -3 +3 -3 +4 -4 +4 -4 diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-EVEN.cob b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-EVEN.cob new file mode 100644 index 0000000..77529d2 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-EVEN.cob @@ -0,0 +1,55 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDED_NEAREST-EVEN.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 M PIC S9. + 01 N PIC S9. + 01 O PIC S9. + 01 P PIC S9. + 01 Q PIC S9. + 01 R PIC S9. + 01 S PIC S9. + 01 T PIC S9. + 01 U PIC S9. + 01 V PIC S9. + PROCEDURE DIVISION. + COMPUTE M ROUNDED MODE NEAREST-EVEN + = 2.49 + END-COMPUTE + COMPUTE N ROUNDED MODE NEAREST-EVEN + = -2.49 + END-COMPUTE + COMPUTE O ROUNDED MODE NEAREST-EVEN + = 2.50 + END-COMPUTE + COMPUTE P ROUNDED MODE NEAREST-EVEN + = -2.50 + END-COMPUTE + COMPUTE Q ROUNDED MODE NEAREST-EVEN + = 3.49 + END-COMPUTE + COMPUTE R ROUNDED MODE NEAREST-EVEN + = -3.49 + END-COMPUTE + COMPUTE S ROUNDED MODE NEAREST-EVEN + = 3.50 + END-COMPUTE + COMPUTE T ROUNDED MODE NEAREST-EVEN + = -3.50 + END-COMPUTE + COMPUTE U ROUNDED MODE NEAREST-EVEN + = 3.510 + END-COMPUTE + COMPUTE V ROUNDED MODE NEAREST-EVEN + = -3.510 + END-COMPUTE + DISPLAY M " " N " " O " " P " " Q " " R " " S " " T + " " U " " V + NO ADVANCING + END-DISPLAY + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-EVEN.out b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-EVEN.out new file mode 100644 index 0000000..59e459b --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-EVEN.out @@ -0,0 +1 @@ ++2 -2 +2 -2 +3 -3 +4 -4 +4 -4 diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-TOWARD-ZERO.cob b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-TOWARD-ZERO.cob new file mode 100644 index 0000000..6f3f28d --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-TOWARD-ZERO.cob @@ -0,0 +1,55 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDED_NEAREST-TOWARD-ZERO.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 M PIC S9. + 01 N PIC S9. + 01 O PIC S9. + 01 P PIC S9. + 01 Q PIC S9. + 01 R PIC S9. + 01 S PIC S9. + 01 T PIC S9. + 01 U PIC S9. + 01 V PIC S9. + PROCEDURE DIVISION. + COMPUTE M ROUNDED MODE NEAREST-TOWARD-ZERO + = 2.49 + END-COMPUTE + COMPUTE N ROUNDED MODE NEAREST-TOWARD-ZERO + = -2.49 + END-COMPUTE + COMPUTE O ROUNDED MODE NEAREST-TOWARD-ZERO + = 2.50 + END-COMPUTE + COMPUTE P ROUNDED MODE NEAREST-TOWARD-ZERO + = -2.50 + END-COMPUTE + COMPUTE Q ROUNDED MODE NEAREST-TOWARD-ZERO + = 3.49 + END-COMPUTE + COMPUTE R ROUNDED MODE NEAREST-TOWARD-ZERO + = -3.49 + END-COMPUTE + COMPUTE S ROUNDED MODE NEAREST-TOWARD-ZERO + = 3.50 + END-COMPUTE + COMPUTE T ROUNDED MODE NEAREST-TOWARD-ZERO + = -3.50 + END-COMPUTE + COMPUTE U ROUNDED MODE NEAREST-TOWARD-ZERO + = 3.510 + END-COMPUTE + COMPUTE V ROUNDED MODE NEAREST-TOWARD-ZERO + = -3.510 + END-COMPUTE + DISPLAY M " " N " " O " " P " " Q " " R " " S " " T + " " U " " V + NO ADVANCING + END-DISPLAY + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-TOWARD-ZERO.out b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-TOWARD-ZERO.out new file mode 100644 index 0000000..05ce11c --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-TOWARD-ZERO.out @@ -0,0 +1 @@ ++2 -2 +2 -2 +3 -3 +3 -3 +4 -4 diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-GREATER.cob b/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-GREATER.cob new file mode 100644 index 0000000..c2b3cf8 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-GREATER.cob @@ -0,0 +1,55 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDED_TOWARD-GREATER.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 M PIC S9. + 01 N PIC S9. + 01 O PIC S9. + 01 P PIC S9. + 01 Q PIC S9. + 01 R PIC S9. + 01 S PIC S9. + 01 T PIC S9. + 01 U PIC S9. + 01 V PIC S9. + PROCEDURE DIVISION. + COMPUTE M ROUNDED MODE TOWARD-GREATER + = 2.49 + END-COMPUTE + COMPUTE N ROUNDED MODE TOWARD-GREATER + = -2.49 + END-COMPUTE + COMPUTE O ROUNDED MODE TOWARD-GREATER + = 2.50 + END-COMPUTE + COMPUTE P ROUNDED MODE TOWARD-GREATER + = -2.50 + END-COMPUTE + COMPUTE Q ROUNDED MODE TOWARD-GREATER + = 3.49 + END-COMPUTE + COMPUTE R ROUNDED MODE TOWARD-GREATER + = -3.49 + END-COMPUTE + COMPUTE S ROUNDED MODE TOWARD-GREATER + = 3.50 + END-COMPUTE + COMPUTE T ROUNDED MODE TOWARD-GREATER + = -3.50 + END-COMPUTE + COMPUTE U ROUNDED MODE TOWARD-GREATER + = 3.510 + END-COMPUTE + COMPUTE V ROUNDED MODE TOWARD-GREATER + = -3.510 + END-COMPUTE + DISPLAY M " " N " " O " " P " " Q " " R " " S " " T + " " U " " V + NO ADVANCING + END-DISPLAY + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-GREATER.out b/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-GREATER.out new file mode 100644 index 0000000..54ab7f3 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-GREATER.out @@ -0,0 +1 @@ ++3 -2 +3 -2 +4 -3 +4 -3 +4 -3 diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-LESSER.cob b/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-LESSER.cob new file mode 100644 index 0000000..37c1749 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-LESSER.cob @@ -0,0 +1,55 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDED_TOWARD-LESSER.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 M PIC S9. + 01 N PIC S9. + 01 O PIC S9. + 01 P PIC S9. + 01 Q PIC S9. + 01 R PIC S9. + 01 S PIC S9. + 01 T PIC S9. + 01 U PIC S9. + 01 V PIC S9. + PROCEDURE DIVISION. + COMPUTE M ROUNDED MODE TOWARD-LESSER + = 2.49 + END-COMPUTE + COMPUTE N ROUNDED MODE TOWARD-LESSER + = -2.49 + END-COMPUTE + COMPUTE O ROUNDED MODE TOWARD-LESSER + = 2.50 + END-COMPUTE + COMPUTE P ROUNDED MODE TOWARD-LESSER + = -2.50 + END-COMPUTE + COMPUTE Q ROUNDED MODE TOWARD-LESSER + = 3.49 + END-COMPUTE + COMPUTE R ROUNDED MODE TOWARD-LESSER + = -3.49 + END-COMPUTE + COMPUTE S ROUNDED MODE TOWARD-LESSER + = 3.50 + END-COMPUTE + COMPUTE T ROUNDED MODE TOWARD-LESSER + = -3.50 + END-COMPUTE + COMPUTE U ROUNDED MODE TOWARD-LESSER + = 3.510 + END-COMPUTE + COMPUTE V ROUNDED MODE TOWARD-LESSER + = -3.510 + END-COMPUTE + DISPLAY M " " N " " O " " P " " Q " " R " " S " " T + " " U " " V + NO ADVANCING + END-DISPLAY + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-LESSER.out b/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-LESSER.out new file mode 100644 index 0000000..2cf5645 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-LESSER.out @@ -0,0 +1 @@ ++2 -3 +2 -3 +3 -4 +3 -4 +3 -4 diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_TRUNCATION.cob b/gcc/testsuite/cobol.dg/group2/ROUNDED_TRUNCATION.cob new file mode 100644 index 0000000..9f46dc7 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_TRUNCATION.cob @@ -0,0 +1,55 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDED_TRUNCATION.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 M PIC S9. + 01 N PIC S9. + 01 O PIC S9. + 01 P PIC S9. + 01 Q PIC S9. + 01 R PIC S9. + 01 S PIC S9. + 01 T PIC S9. + 01 U PIC S9. + 01 V PIC S9. + PROCEDURE DIVISION. + COMPUTE M ROUNDED MODE TRUNCATION + = 2.49 + END-COMPUTE + COMPUTE N ROUNDED MODE TRUNCATION + = -2.49 + END-COMPUTE + COMPUTE O ROUNDED MODE TRUNCATION + = 2.50 + END-COMPUTE + COMPUTE P ROUNDED MODE TRUNCATION + = -2.50 + END-COMPUTE + COMPUTE Q ROUNDED MODE TRUNCATION + = 3.49 + END-COMPUTE + COMPUTE R ROUNDED MODE TRUNCATION + = -3.49 + END-COMPUTE + COMPUTE S ROUNDED MODE TRUNCATION + = 3.50 + END-COMPUTE + COMPUTE T ROUNDED MODE TRUNCATION + = -3.50 + END-COMPUTE + COMPUTE U ROUNDED MODE TRUNCATION + = 3.510 + END-COMPUTE + COMPUTE V ROUNDED MODE TRUNCATION + = -3.510 + END-COMPUTE + DISPLAY M " " N " " O " " P " " Q " " R " " S " " T + " " U " " V + NO ADVANCING + END-DISPLAY + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDED_TRUNCATION.out b/gcc/testsuite/cobol.dg/group2/ROUNDED_TRUNCATION.out new file mode 100644 index 0000000..c178d5a --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDED_TRUNCATION.out @@ -0,0 +1 @@ ++2 -2 +2 -2 +3 -3 +3 -3 +3 -3 diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.cob b/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.cob new file mode 100644 index 0000000..4bc8b28 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.cob @@ -0,0 +1,427 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.out" } + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 VAR1 COMP-2. + 01 VAR2 PICTURE S999. + 01 SHOULD_BE PICTURE S999. + 01 RMODE PICTURE X(64). + 01 EMPTY PIC X VALUE " ". + 01 FLAG PIC X. + PROCEDURE DIVISION. + + DISPLAY "ROUNDING from COMP-2 after COMPUTE." + + PERFORM truncation-e. + PERFORM truncation-m. + PERFORM nearest-away-from-zero-e. + PERFORM nearest-away-from-zero-m. + PERFORM away-from-zero-e. + PERFORM away-from-zero-m. + PERFORM nearest-even-e. + PERFORM nearest-even-m. + PERFORM nearest-toward-zero-e. + PERFORM nearest-toward-zero-m. + PERFORM toward-greater-e. + PERFORM toward-greater-m. + PERFORM toward-lesser-e. + PERFORM toward-lesser-m. + PERFORM prohibited-e. + GOBACK. + + truncation-e. + MOVE "TRUNCATION" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + + truncation-m. + MOVE "TRUNCATION" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + + nearest-away-from-zero-e. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + nearest-away-from-zero-m. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + away-from-zero-e. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + away-from-zero-m. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + nearest-even-e. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 110.0 TO VAR1 + MOVE 110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 110.1 TO VAR1 + MOVE 110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 110.5 TO VAR1 + MOVE 110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 110.9 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + MOVE "NEAREST-EVEN" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + + nearest-even-m. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -110.0 TO VAR1 + MOVE -110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -110.1 TO VAR1 + MOVE -110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -110.5 TO VAR1 + MOVE -110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -110.9 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + MOVE "NEAREST-EVEN" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + + nearest-toward-zero-e. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + nearest-toward-zero-m. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + toward-greater-e. + MOVE "TOWARD-GREATER" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + + toward-greater-m. + MOVE "TOWARD-GREATER" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + + toward-lesser-e. + MOVE "TOWARD-LESSER" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + + toward-lesser-m. + MOVE "TOWARD-LESSER" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + + prohibited-e. + MOVE "PROHIBITED - fits" TO RMODE + SET LAST EXCEPTION TO OFF + MOVE 123 TO VAR2 + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE PROHIBITED = VAR1 + PERFORM SHOW_RESULTS + DISPLAY " EXCEPTION STATUS IS " + """" FUNCTION TRIM(FUNCTION EXCEPTION-STATUS) """". + + MOVE "PROHIBITED - doesn't fit; no ON ERROR phrase" TO RMODE + SET LAST EXCEPTION TO OFF + MOVE 123 TO VAR2 + MOVE 111.5 TO VAR1 + MOVE 123 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE PROHIBITED = VAR1 + PERFORM SHOW_RESULTS + DISPLAY " EXCEPTION STATUS IS " + """" FUNCTION TRIM(FUNCTION EXCEPTION-STATUS) """". + + MOVE "PROHIBITED - doesn't fit; ON ERROR phrase" TO RMODE + SET LAST EXCEPTION TO OFF + MOVE SPACE TO FLAG + MOVE 123 TO VAR2 + MOVE 111.5 TO VAR1 + MOVE 123 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE PROHIBITED = VAR1 + ON SIZE ERROR MOVE 'X' TO FLAG + END-COMPUTE + PERFORM SHOW_RESULTS + IF FLAG EQUAL 'X' + DISPLAY " COMPUTE had an ON SIZE error" + END-IF. + DISPLAY " EXCEPTION STATUS IS " + """" FUNCTION TRIM(FUNCTION EXCEPTION-STATUS) """". + + SHOW_RESULTS. + DISPLAY "Rounding mode " FUNCTION TRIM(RMODE) + " " VAR1 " becomes " VAR2 + WITH NO ADVANCING + END-DISPLAY + IF VAR2 EQUALS SHOULD_BE + DISPLAY FUNCTION TRIM(EMPTY) + ELSE + DISPLAY " but it should be " SHOULD_BE + END-IF. + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.out b/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.out new file mode 100644 index 0000000..4ff4e29 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.out @@ -0,0 +1,71 @@ +ROUNDING from COMP-2 after COMPUTE. +Rounding mode TRUNCATION 111 becomes +111 +Rounding mode TRUNCATION 111.099999999999994 becomes +111 +Rounding mode TRUNCATION 111.5 becomes +111 +Rounding mode TRUNCATION 111.900000000000006 becomes +111 +Rounding mode TRUNCATION -111 becomes -111 +Rounding mode TRUNCATION -111.099999999999994 becomes -111 +Rounding mode TRUNCATION -111.5 becomes -111 +Rounding mode TRUNCATION -111.900000000000006 becomes -111 +Rounding mode NEAREST-AWAY-FROM-ZERO 111 becomes +111 +Rounding mode NEAREST-AWAY-FROM-ZERO 111.099999999999994 becomes +111 +Rounding mode NEAREST-AWAY-FROM-ZERO 111.5 becomes +112 +Rounding mode NEAREST-AWAY-FROM-ZERO 111.900000000000006 becomes +112 +Rounding mode NEAREST-AWAY-FROM-ZERO -111 becomes -111 +Rounding mode NEAREST-AWAY-FROM-ZERO -111.099999999999994 becomes -111 +Rounding mode NEAREST-AWAY-FROM-ZERO -111.5 becomes -112 +Rounding mode NEAREST-AWAY-FROM-ZERO -111.900000000000006 becomes -112 +Rounding mode AWAY-FROM-ZERO 111 becomes +111 +Rounding mode AWAY-FROM-ZERO 111.099999999999994 becomes +112 +Rounding mode AWAY-FROM-ZERO 111.5 becomes +112 +Rounding mode AWAY-FROM-ZERO 111.900000000000006 becomes +112 +Rounding mode AWAY-FROM-ZERO -111 becomes -111 +Rounding mode AWAY-FROM-ZERO -111.099999999999994 becomes -112 +Rounding mode AWAY-FROM-ZERO -111.5 becomes -112 +Rounding mode AWAY-FROM-ZERO -111.900000000000006 becomes -112 +Rounding mode NEAREST-EVEN 110 becomes +110 +Rounding mode NEAREST-EVEN 110.099999999999994 becomes +110 +Rounding mode NEAREST-EVEN 110.5 becomes +110 +Rounding mode NEAREST-EVEN 111 becomes +111 +Rounding mode NEAREST-EVEN 111.099999999999994 becomes +111 +Rounding mode NEAREST-EVEN 111.5 becomes +112 +Rounding mode NEAREST-EVEN 111.900000000000006 becomes +112 +Rounding mode NEAREST-EVEN -110 becomes -110 +Rounding mode NEAREST-EVEN -110.099999999999994 becomes -110 +Rounding mode NEAREST-EVEN -110.5 becomes -110 +Rounding mode NEAREST-EVEN -111 becomes -111 +Rounding mode NEAREST-EVEN -111.099999999999994 becomes -111 +Rounding mode NEAREST-EVEN -111.5 becomes -112 +Rounding mode NEAREST-EVEN -111.900000000000006 becomes -112 +Rounding mode NEAREST-TOWARD-ZERO 111 becomes +111 +Rounding mode NEAREST-TOWARD-ZERO 111.099999999999994 becomes +111 +Rounding mode NEAREST-TOWARD-ZERO 111.5 becomes +111 +Rounding mode NEAREST-TOWARD-ZERO 111.900000000000006 becomes +112 +Rounding mode NEAREST-TOWARD-ZERO -111 becomes -111 +Rounding mode NEAREST-TOWARD-ZERO -111.099999999999994 becomes -111 +Rounding mode NEAREST-TOWARD-ZERO -111.5 becomes -111 +Rounding mode NEAREST-TOWARD-ZERO -111.900000000000006 becomes -112 +Rounding mode TOWARD-GREATER 111 becomes +111 +Rounding mode TOWARD-GREATER 111.099999999999994 becomes +112 +Rounding mode TOWARD-GREATER 111.5 becomes +112 +Rounding mode TOWARD-GREATER 111.900000000000006 becomes +112 +Rounding mode TOWARD-GREATER -111 becomes -111 +Rounding mode TOWARD-GREATER -111.099999999999994 becomes -111 +Rounding mode TOWARD-GREATER -111.5 becomes -111 +Rounding mode TOWARD-GREATER -111.900000000000006 becomes -111 +Rounding mode TOWARD-LESSER 111 becomes +111 +Rounding mode TOWARD-LESSER 111.099999999999994 becomes +111 +Rounding mode TOWARD-LESSER 111.5 becomes +111 +Rounding mode TOWARD-LESSER 111.900000000000006 becomes +111 +Rounding mode TOWARD-LESSER -111 becomes -111 +Rounding mode TOWARD-LESSER -111.099999999999994 becomes -112 +Rounding mode TOWARD-LESSER -111.5 becomes -112 +Rounding mode TOWARD-LESSER -111.900000000000006 becomes -112 +Rounding mode PROHIBITED - fits 111 becomes +111 + EXCEPTION STATUS IS "" +Rounding mode PROHIBITED - doesn't fit; no ON ERROR phrase 111.5 becomes +123 + EXCEPTION STATUS IS "EC-SIZE-TRUNCATION" +Rounding mode PROHIBITED - doesn't fit; ON ERROR phrase 111.5 becomes +123 + COMPUTE had an ON SIZE error + EXCEPTION STATUS IS "EC-SIZE-TRUNCATION" + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.cob b/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.cob new file mode 100644 index 0000000..3138233 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.cob @@ -0,0 +1,428 @@ + *> { dg-do run } + *> { dg-output-file "group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.out" } + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 VAR1 PICTURE S999V9. + 01 VAR2 PICTURE S999. + 01 SHOULD_BE PICTURE S999. + 01 RMODE PICTURE X(64). + 01 EMPTY PIC X VALUE " ". + 01 FLAG PIC X. + PROCEDURE DIVISION. + + DISPLAY "ROUNDING from NumericDisplay after COMPUTE." + + PERFORM truncation-e. + PERFORM truncation-m. + PERFORM nearest-away-from-zero-e. + PERFORM nearest-away-from-zero-m. + PERFORM away-from-zero-e. + PERFORM away-from-zero-m. + PERFORM nearest-even-e. + PERFORM nearest-even-m. + PERFORM nearest-toward-zero-e. + PERFORM nearest-toward-zero-m. + PERFORM toward-greater-e. + PERFORM toward-greater-m. + PERFORM toward-lesser-e. + PERFORM toward-lesser-m. + PERFORM prohibited-e. + GOBACK. + + truncation-e. + MOVE "TRUNCATION" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + + truncation-m. + MOVE "TRUNCATION" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TRUNCATION" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TRUNCATION = VAR1 + PERFORM SHOW_RESULTS. + + nearest-away-from-zero-e. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + nearest-away-from-zero-m. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-AWAY-FROM-ZERO" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + away-from-zero-e. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + away-from-zero-m. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "AWAY-FROM-ZERO" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE AWAY-FROM-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + nearest-even-e. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 110.0 TO VAR1 + MOVE 110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 110.1 TO VAR1 + MOVE 110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 110.5 TO VAR1 + MOVE 110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 110.9 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + MOVE "NEAREST-EVEN" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + + nearest-even-m. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -110.0 TO VAR1 + MOVE -110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -110.1 TO VAR1 + MOVE -110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -110.5 TO VAR1 + MOVE -110 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -110.9 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + MOVE "NEAREST-EVEN" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-EVEN" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-EVEN = VAR1 + PERFORM SHOW_RESULTS. + + nearest-toward-zero-e. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + nearest-toward-zero-m. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + MOVE "NEAREST-TOWARD-ZERO" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE NEAREST-TOWARD-ZERO = VAR1 + PERFORM SHOW_RESULTS. + + toward-greater-e. + MOVE "TOWARD-GREATER" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + + toward-greater-m. + MOVE "TOWARD-GREATER" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-GREATER" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-GREATER = VAR1 + PERFORM SHOW_RESULTS. + + toward-lesser-e. + MOVE "TOWARD-LESSER" TO RMODE + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE 111.1 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE 111.5 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE 111.9 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + + toward-lesser-m. + MOVE "TOWARD-LESSER" TO RMODE + MOVE -111.0 TO VAR1 + MOVE -111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE -111.1 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE -111.5 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + MOVE "TOWARD-LESSER" TO RMODE + MOVE -111.9 TO VAR1 + MOVE -112 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE TOWARD-LESSER = VAR1 + PERFORM SHOW_RESULTS. + + prohibited-e. + MOVE "PROHIBITED - fits" TO RMODE + SET LAST EXCEPTION TO OFF + MOVE 123 TO VAR2 + MOVE 111.0 TO VAR1 + MOVE 111 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE PROHIBITED = VAR1 + PERFORM SHOW_RESULTS + DISPLAY " EXCEPTION STATUS IS " + """" FUNCTION TRIM(FUNCTION EXCEPTION-STATUS) """". + + MOVE "PROHIBITED - doesn't fit; no ON ERROR phrase" TO RMODE + SET LAST EXCEPTION TO OFF + MOVE 123 TO VAR2 + MOVE 111.5 TO VAR1 + MOVE 123 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE PROHIBITED = VAR1 + PERFORM SHOW_RESULTS + DISPLAY " EXCEPTION STATUS IS " + """" FUNCTION TRIM(FUNCTION EXCEPTION-STATUS) """". + + MOVE "PROHIBITED - doesn't fit; ON ERROR phrase" TO RMODE + SET LAST EXCEPTION TO OFF + MOVE SPACE TO FLAG + MOVE 123 TO VAR2 + MOVE 111.5 TO VAR1 + MOVE 123 TO SHOULD_BE + COMPUTE VAR2 ROUNDED MODE PROHIBITED = VAR1 + ON SIZE ERROR MOVE 'X' TO FLAG + END-COMPUTE + PERFORM SHOW_RESULTS + IF FLAG EQUAL 'X' + DISPLAY " COMPUTE had an ON SIZE error" + END-IF. + DISPLAY " EXCEPTION STATUS IS " + """" FUNCTION TRIM(FUNCTION EXCEPTION-STATUS) """". + + SHOW_RESULTS. + DISPLAY "Rounding mode " FUNCTION TRIM(RMODE) + " " VAR1 " becomes " VAR2 + WITH NO ADVANCING + END-DISPLAY + IF VAR2 EQUALS SHOULD_BE + DISPLAY FUNCTION TRIM(EMPTY) + ELSE + DISPLAY " but it should be " SHOULD_BE + END-IF. + + diff --git a/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.out b/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.out new file mode 100644 index 0000000..af94786 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.out @@ -0,0 +1,71 @@ +ROUNDING from NumericDisplay after COMPUTE. +Rounding mode TRUNCATION +111.0 becomes +111 +Rounding mode TRUNCATION +111.1 becomes +111 +Rounding mode TRUNCATION +111.5 becomes +111 +Rounding mode TRUNCATION +111.9 becomes +111 +Rounding mode TRUNCATION -111.0 becomes -111 +Rounding mode TRUNCATION -111.1 becomes -111 +Rounding mode TRUNCATION -111.5 becomes -111 +Rounding mode TRUNCATION -111.9 becomes -111 +Rounding mode NEAREST-AWAY-FROM-ZERO +111.0 becomes +111 +Rounding mode NEAREST-AWAY-FROM-ZERO +111.1 becomes +111 +Rounding mode NEAREST-AWAY-FROM-ZERO +111.5 becomes +112 +Rounding mode NEAREST-AWAY-FROM-ZERO +111.9 becomes +112 +Rounding mode NEAREST-AWAY-FROM-ZERO -111.0 becomes -111 +Rounding mode NEAREST-AWAY-FROM-ZERO -111.1 becomes -111 +Rounding mode NEAREST-AWAY-FROM-ZERO -111.5 becomes -112 +Rounding mode NEAREST-AWAY-FROM-ZERO -111.9 becomes -112 +Rounding mode AWAY-FROM-ZERO +111.0 becomes +111 +Rounding mode AWAY-FROM-ZERO +111.1 becomes +112 +Rounding mode AWAY-FROM-ZERO +111.5 becomes +112 +Rounding mode AWAY-FROM-ZERO +111.9 becomes +112 +Rounding mode AWAY-FROM-ZERO -111.0 becomes -111 +Rounding mode AWAY-FROM-ZERO -111.1 becomes -112 +Rounding mode AWAY-FROM-ZERO -111.5 becomes -112 +Rounding mode AWAY-FROM-ZERO -111.9 becomes -112 +Rounding mode NEAREST-EVEN +110.0 becomes +110 +Rounding mode NEAREST-EVEN +110.1 becomes +110 +Rounding mode NEAREST-EVEN +110.5 becomes +110 +Rounding mode NEAREST-EVEN +111.0 becomes +111 +Rounding mode NEAREST-EVEN +111.1 becomes +111 +Rounding mode NEAREST-EVEN +111.5 becomes +112 +Rounding mode NEAREST-EVEN +111.9 becomes +112 +Rounding mode NEAREST-EVEN -110.0 becomes -110 +Rounding mode NEAREST-EVEN -110.1 becomes -110 +Rounding mode NEAREST-EVEN -110.5 becomes -110 +Rounding mode NEAREST-EVEN -111.0 becomes -111 +Rounding mode NEAREST-EVEN -111.1 becomes -111 +Rounding mode NEAREST-EVEN -111.5 becomes -112 +Rounding mode NEAREST-EVEN -111.9 becomes -112 +Rounding mode NEAREST-TOWARD-ZERO +111.0 becomes +111 +Rounding mode NEAREST-TOWARD-ZERO +111.1 becomes +111 +Rounding mode NEAREST-TOWARD-ZERO +111.5 becomes +111 +Rounding mode NEAREST-TOWARD-ZERO +111.9 becomes +112 +Rounding mode NEAREST-TOWARD-ZERO -111.0 becomes -111 +Rounding mode NEAREST-TOWARD-ZERO -111.1 becomes -111 +Rounding mode NEAREST-TOWARD-ZERO -111.5 becomes -111 +Rounding mode NEAREST-TOWARD-ZERO -111.9 becomes -112 +Rounding mode TOWARD-GREATER +111.0 becomes +111 +Rounding mode TOWARD-GREATER +111.1 becomes +112 +Rounding mode TOWARD-GREATER +111.5 becomes +112 +Rounding mode TOWARD-GREATER +111.9 becomes +112 +Rounding mode TOWARD-GREATER -111.0 becomes -111 +Rounding mode TOWARD-GREATER -111.1 becomes -111 +Rounding mode TOWARD-GREATER -111.5 becomes -111 +Rounding mode TOWARD-GREATER -111.9 becomes -111 +Rounding mode TOWARD-LESSER +111.0 becomes +111 +Rounding mode TOWARD-LESSER +111.1 becomes +111 +Rounding mode TOWARD-LESSER +111.5 becomes +111 +Rounding mode TOWARD-LESSER +111.9 becomes +111 +Rounding mode TOWARD-LESSER -111.0 becomes -111 +Rounding mode TOWARD-LESSER -111.1 becomes -112 +Rounding mode TOWARD-LESSER -111.5 becomes -112 +Rounding mode TOWARD-LESSER -111.9 becomes -112 +Rounding mode PROHIBITED - fits +111.0 becomes +111 + EXCEPTION STATUS IS "" +Rounding mode PROHIBITED - doesn't fit; no ON ERROR phrase +111.5 becomes +123 + EXCEPTION STATUS IS "EC-SIZE-TRUNCATION" +Rounding mode PROHIBITED - doesn't fit; ON ERROR phrase +111.5 becomes +123 + COMPUTE had an ON SIZE error + EXCEPTION STATUS IS "EC-SIZE-TRUNCATION" + diff --git a/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__1_.cob b/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__1_.cob new file mode 100644 index 0000000..631b48e --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__1_.cob @@ -0,0 +1,16 @@ + *> { dg-do run } + *> { dg-output-file "group2/Separate_sign_positions__1_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC S9 VALUE -1 SIGN LEADING SEPARATE. + 01 Y PIC S9 VALUE -1 SIGN TRAILING SEPARATE. + PROCEDURE DIVISION. + DISPLAY X(1:1) X(2:1) NO ADVANCING + END-DISPLAY. + DISPLAY Y(1:1) Y(2:1) NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__1_.out b/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__1_.out new file mode 100644 index 0000000..d981f48 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__1_.out @@ -0,0 +1 @@ +-11- diff --git a/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__2_.cob b/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__2_.cob new file mode 100644 index 0000000..1c6b423 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__2_.cob @@ -0,0 +1,24 @@ + *> { dg-do run } + *> { dg-output-file "group2/Separate_sign_positions__2_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC S9 SIGN LEADING SEPARATE. + 01 Y PIC S9 SIGN TRAILING SEPARATE. + PROCEDURE DIVISION. + MOVE 0 TO X. + DISPLAY X NO ADVANCING + END-DISPLAY. + MOVE ZERO TO X. + DISPLAY X NO ADVANCING + END-DISPLAY. + MOVE 0 TO Y. + DISPLAY Y NO ADVANCING + END-DISPLAY. + MOVE ZERO TO Y. + DISPLAY Y NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__2_.out b/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__2_.out new file mode 100644 index 0000000..6d2ea72 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Separate_sign_positions__2_.out @@ -0,0 +1 @@ ++0+00+0+ diff --git a/gcc/testsuite/cobol.dg/group2/Simple_TYPEDEF.cob b/gcc/testsuite/cobol.dg/group2/Simple_TYPEDEF.cob new file mode 100644 index 0000000..c2fffbe --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Simple_TYPEDEF.cob @@ -0,0 +1,16 @@ + *> { dg-do run } + *> { dg-options "-dialect mf" } + + identification division. + program-id. wrapper. + data division. + working-storage section. + 77 UNS-CHAR PIC 9(02) COMP-5 IS TYPEDEF. + 01 Z-H3 PIC X(017) . + 01 I-H3A USAGE UNS-CHAR. + 01 I-H3B USAGE UNS-CHAR. + 78 I-H3-max VALUE LENGTH OF Z-H3. + procedure division. + goback. + end program wrapper. + diff --git a/gcc/testsuite/cobol.dg/group2/Simple_p-scaling.cob b/gcc/testsuite/cobol.dg/group2/Simple_p-scaling.cob new file mode 100644 index 0000000..db3bc41 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Simple_p-scaling.cob @@ -0,0 +1,33 @@ + *> { dg-do run } + *> { dg-output-file "group2/Simple_p-scaling.out" } + + identification division. + program-id. prog. + data division. + working-storage section. + 01 vars. + 05 vars01 picture 99ppp DISPLAY value 78000 . + 05 vars02 picture 99ppp BINARY value 78000 . + 05 vars03 picture 99ppp COMP-3 value 78000 . + 05 vars04 picture 99ppp COMP-5 value 78000 . + 05 vars05 picture 99ppp PACKED-DECIMAL value 78000 . + 01 vary. + 05 vary01 picture ppp99 DISPLAY value 0.00078 . + 05 vary02 picture ppp99 BINARY value 0.00078 . + 05 vary03 picture ppp99 COMP-3 value 0.00078 . + 05 vary04 picture ppp99 COMP-5 value 0.00078 . + 05 vary05 picture ppp99 PACKED-DECIMAL value 0.00078 . + procedure division. + display vars01 + display vars02 + display vars03 + display vars04 + display vars05 + display vary01 + display vary02 + display vary03 + display vary04 + display vary05 + goback. + end program prog. + diff --git a/gcc/testsuite/cobol.dg/group2/Simple_p-scaling.out b/gcc/testsuite/cobol.dg/group2/Simple_p-scaling.out new file mode 100644 index 0000000..8d9c45c --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/Simple_p-scaling.out @@ -0,0 +1,11 @@ +78000 +78000 +78000 +78000 +78000 +.00078 +.00078 +.00078 +.00078 +.00078 + diff --git a/gcc/testsuite/cobol.dg/group2/debugging_lines__WITH_DEBUGGING_MODE_.cob b/gcc/testsuite/cobol.dg/group2/debugging_lines__WITH_DEBUGGING_MODE_.cob new file mode 100644 index 0000000..880d865 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/debugging_lines__WITH_DEBUGGING_MODE_.cob @@ -0,0 +1,21 @@ + *> { dg-do run } + *> { dg-options "-ffixed-form" } + *> { dg-output-file "group2/debugging_lines__WITH_DEBUGGING_MODE_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + SOURCE-COMPUTER. mine WITH DEBUGGING MODE. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + * Original "incorrect ordered lines" + * DISPLAY "KO" NO ADVANCING UPON STDOUT + * END-DISPLAY. + D DISPLAY "KO" UPON STDOUT NO ADVANCING + D END-DISPLAY. + DISPLAY "OK" UPON STDOUT NO ADVANCING + END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/debugging_lines__WITH_DEBUGGING_MODE_.out b/gcc/testsuite/cobol.dg/group2/debugging_lines__WITH_DEBUGGING_MODE_.out new file mode 100644 index 0000000..6f0a25f5 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/debugging_lines__WITH_DEBUGGING_MODE_.out @@ -0,0 +1 @@ +KOOK diff --git a/gcc/testsuite/cobol.dg/group2/debugging_lines__not_active_.cob b/gcc/testsuite/cobol.dg/group2/debugging_lines__not_active_.cob new file mode 100644 index 0000000..56cb067 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/debugging_lines__not_active_.cob @@ -0,0 +1,14 @@ + *> { dg-do run } + *> { dg-output-file "group2/debugging_lines__not_active_.out" } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + PROCEDURE DIVISION. + DISPLAY "OK" NO ADVANCING + END-DISPLAY. + D DISPLAY "KO" NO ADVANCING + D END-DISPLAY. + STOP RUN. + diff --git a/gcc/testsuite/cobol.dg/group2/debugging_lines__not_active_.out b/gcc/testsuite/cobol.dg/group2/debugging_lines__not_active_.out new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/debugging_lines__not_active_.out @@ -0,0 +1 @@ +OK diff --git a/gcc/testsuite/cobol.dg/group2/integer_arithmetic_on_floating-point_var.cob b/gcc/testsuite/cobol.dg/group2/integer_arithmetic_on_floating-point_var.cob new file mode 100644 index 0000000..bf7bd78 --- /dev/null +++ b/gcc/testsuite/cobol.dg/group2/integer_arithmetic_on_floating-point_var.cob @@ -0,0 +1,29 @@ + *> { dg-do run } + + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 x USAGE COMP-1 VALUE 123.456. + PROCEDURE DIVISION. + ADD 360 TO x + IF x > 483.457 OR x < 483.455 + DISPLAY "ADD wrong: " x + MOVE 483.456 TO x + END-IF + SUBTRACT 360 FROM x + IF x > 123.457 OR x < 123.455 + DISPLAY "SUBTRACT wrong: " x + MOVE 123.456 TO x + END-IF + DIVIDE 2 INTO x + IF x > 61.729 OR x < 61.727 + DISPLAY "DIVIDE wrong: " x + MOVE 61.728 TO x + END-IF + MULTIPLY 2 BY x + IF x > 123.457 OR x < 123.455 + DISPLAY "MULTIPLY wrong: " x + END-IF + GOBACK. + diff --git a/gcc/testsuite/g++.dg/abi/macro0.C b/gcc/testsuite/g++.dg/abi/macro0.C index f6a57c1..3dd44fc 100644 --- a/gcc/testsuite/g++.dg/abi/macro0.C +++ b/gcc/testsuite/g++.dg/abi/macro0.C @@ -1,6 +1,6 @@ // This testcase will need to be kept in sync with c_common_post_options. // { dg-options "-fabi-version=0" } -#if __GXX_ABI_VERSION != 1020 +#if __GXX_ABI_VERSION != 1021 #error "Incorrect value of __GXX_ABI_VERSION" #endif diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-noexcept1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-noexcept1.C new file mode 100644 index 0000000..d744556 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-noexcept1.C @@ -0,0 +1,10 @@ +// PR c++/119764 +// { dg-do compile { target c++11 } } +// { dg-additional-options "-fabi-version=0 -Wabi=20" } + +int main() { + const int x = 123; + auto a = [&]() { return x; }; + auto b = [&]() noexcept { return x; }; // { dg-warning "no longer captured" } + static_assert(sizeof(a) == sizeof(b), ""); +} diff --git a/gcc/testsuite/g++.dg/template/recurse5.C b/gcc/testsuite/g++.dg/template/recurse5.C new file mode 100644 index 0000000..7bfe523 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/recurse5.C @@ -0,0 +1,17 @@ +// Test that we don't bother to instantiate add since there were errors in +// checked_add. + +template <class T> T add (T t) { return t+1; } // { dg-bogus "no match" } + +template <class T> T checked_add (T t) +{ + add (t); + return t+1; // { dg-error "no match" } +} + +struct A { }; + +int main() +{ + checked_add (A()); +} diff --git a/gcc/testsuite/gcc.dg/pr116479.c b/gcc/testsuite/gcc.dg/pr116479.c new file mode 100644 index 0000000..dbbcb9a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr116479.c @@ -0,0 +1,26 @@ +/* PR 116479 */ +/* { dg-do run { target { bitint } } } */ +/* { dg-additional-options "-O -funroll-loops -finline-stringops -fmodulo-sched --param=max-iterations-computation-cost=637924687 -std=c23" } */ + +#if __BITINT_MAXWIDTH__ >= 13577 +_BitInt (13577) b; + +void +foo (char *ret) +{ + __builtin_memset (&b, 4, 697); + *ret = 0; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 13577 + char x; + foo (&x); + for (unsigned i = 0; i < sizeof (x); i++) + if (x != 0) + __builtin_abort (); +#endif +} diff --git a/gcc/testsuite/gcc.target/i386/pr119919.c b/gcc/testsuite/gcc.target/i386/pr119919.c new file mode 100644 index 0000000..ed64656 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr119919.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -msse2 -fdump-tree-vect-details" } */ +int a[9*9]; +bool b[9]; +void test() +{ + for (int i = 0; i < 9; i++) + { + b[i] = a[i*9] != 0; + } +} + +/* { dg-final { scan-tree-dump "loop vectorized using 8 byte vectors" "vect" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/arch-25.c b/gcc/testsuite/gcc.target/riscv/arch-25.c index 3be4ade..9201883 100644 --- a/gcc/testsuite/gcc.target/riscv/arch-25.c +++ b/gcc/testsuite/gcc.target/riscv/arch-25.c @@ -2,4 +2,4 @@ /* { dg-options "-march=rv64i_zcf -mabi=lp64" } */ int foo() {} /* { dg-error "'-march=rv64i_zcf': zcf extension supports in rv32 only" "" { target *-*-* } 0 } */ -/* { dg-error "'-march=rv64i_zca_zcf': zcf extension supports in rv32 only" "" { target *-*-* } 0 } */ +/* { dg-error "'-march=rv64ic_zca_zcf': zcf extension supports in rv32 only" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-1.c b/gcc/testsuite/gcc.target/riscv/attribute-c-1.c new file mode 100644 index 0000000..5627e16 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32i_zca -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_c2p0_zca1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-2.c b/gcc/testsuite/gcc.target/riscv/attribute-c-2.c new file mode 100644 index 0000000..4c7d5f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-2.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32if_zca -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_zicsr2p0_zca1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-3.c b/gcc/testsuite/gcc.target/riscv/attribute-c-3.c new file mode 100644 index 0000000..7ff68f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-3.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32if_zca_zcf -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_c2p0_zicsr2p0_zca1p0_zcf1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-4.c b/gcc/testsuite/gcc.target/riscv/attribute-c-4.c new file mode 100644 index 0000000..ef59b65 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-4.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32ifd_zca_zcf -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_d2p2_zicsr2p0_zca1p0_zcf1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-5.c b/gcc/testsuite/gcc.target/riscv/attribute-c-5.c new file mode 100644 index 0000000..14e9551 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-5.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv32ifd_zca_zcf_zcd -mabi=ilp32" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0_zcf1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-6.c b/gcc/testsuite/gcc.target/riscv/attribute-c-6.c new file mode 100644 index 0000000..30cda55 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-6.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv64i_zca -mabi=lp64" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_c2p0_zca1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-7.c b/gcc/testsuite/gcc.target/riscv/attribute-c-7.c new file mode 100644 index 0000000..b06388b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-7.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv64ifd_zca -mabi=lp64" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_f2p2_d2p2_zicsr2p0_zca1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-c-8.c b/gcc/testsuite/gcc.target/riscv/attribute-c-8.c new file mode 100644 index 0000000..fa76050 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/attribute-c-8.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mriscv-attribute -march=rv64ifd_zca_zcd -mabi=lp64" } */ + +void foo(){} + +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_f2p2_d2p2_c2p0_zicsr2p0_zca1p0_zcd1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-zce-1.c b/gcc/testsuite/gcc.target/riscv/attribute-zce-1.c index e477414..fc86dbe 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-zce-1.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-zce-1.c @@ -3,4 +3,4 @@ void foo(){} -/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-zce-2.c b/gcc/testsuite/gcc.target/riscv/attribute-zce-2.c index 7008eb5..4504158 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-zce-2.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-zce-2.c @@ -3,4 +3,4 @@ void foo(){} -/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p1_f2p2_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcf1p0_zcmp1p0_zcmt1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-zce-3.c b/gcc/testsuite/gcc.target/riscv/attribute-zce-3.c index 89ebaaf..4ffc051 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-zce-3.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-zce-3.c @@ -3,4 +3,4 @@ void foo(){} -/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/attribute-zce-4.c b/gcc/testsuite/gcc.target/riscv/attribute-zce-4.c index cacbcaa..7ee8de2 100644 --- a/gcc/testsuite/gcc.target/riscv/attribute-zce-4.c +++ b/gcc/testsuite/gcc.target/riscv/attribute-zce-4.c @@ -3,4 +3,4 @@ void foo(){} -/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_f2p2_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ +/* { dg-final { scan-assembler ".attribute arch, \"rv64i2p1_f2p2_c2p0_zicsr2p0_zca1p0_zcb1p0_zce1p0_zcmp1p0_zcmt1p0\"" } } */ diff --git a/gcc/testsuite/gcc.target/s390/pr119873-1.c b/gcc/testsuite/gcc.target/s390/pr119873-1.c new file mode 100644 index 0000000..7a9a988 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr119873-1.c @@ -0,0 +1,11 @@ +/* PR target/119873 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +const char *foo (void *, void *, void *, void *, unsigned long, unsigned long); + +const char * +bar (void *a, void *b, void *c, void *d, unsigned long e, unsigned long f) +{ + [[gnu::musttail]] return foo (a, b, c, d, e, f); +} diff --git a/gcc/testsuite/gcc.target/s390/pr119873-2.c b/gcc/testsuite/gcc.target/s390/pr119873-2.c new file mode 100644 index 0000000..f275253 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr119873-2.c @@ -0,0 +1,17 @@ +/* PR target/119873 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +const char *foo (void *, void *, void *, void *, unsigned long, unsigned long); + +const char * +bar (void *a, void *b, void *c, void *d, unsigned long e, unsigned long f) +{ + [[gnu::musttail]] return foo (a, b, c, d, e + 1, f); /* { dg-error "cannot tail-call: target is not able to optimize the call into a sibling call" } */ +} + +const char * +baz (void *a, void *b, void *c, void *d, unsigned long e, unsigned long f) +{ + [[gnu::musttail]] return foo (a, b, c, d, f, e); /* { dg-error "cannot tail-call: target is not able to optimize the call into a sibling call" } */ +} diff --git a/gcc/testsuite/gcc.target/s390/pr119873-3.c b/gcc/testsuite/gcc.target/s390/pr119873-3.c new file mode 100644 index 0000000..048fcaa --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr119873-3.c @@ -0,0 +1,27 @@ +/* PR target/119873 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern int foo (int, int, int, long long, int); + +int +bar (int u, int v, int w, long long x, int y) +{ + [[gnu::musttail]] return foo (u, v, w, x, y); +} + +extern int baz (int, int, int, int, int); + +int +qux (int u, int v, int w, int x, int y) +{ + [[gnu::musttail]] return baz (u, v, w, x, y); +} + +extern int corge (int, int, int, int, unsigned short); + +int +garply (int u, int v, int w, int x, unsigned short y) +{ + [[gnu::musttail]] return corge (u, v, w, x, y); +} diff --git a/gcc/testsuite/gcc.target/s390/pr119873-4.c b/gcc/testsuite/gcc.target/s390/pr119873-4.c new file mode 100644 index 0000000..384170c --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr119873-4.c @@ -0,0 +1,27 @@ +/* PR target/119873 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern int foo (int, int, int, long long, int); + +int +bar (int u, int v, int w, long long x, int y) +{ + [[gnu::musttail]] return foo (u, v, w, x + 1, y - 1); /* { dg-error "cannot tail-call: target is not able to optimize the call into a sibling call" } */ +} + +extern int baz (int, int, int, int, int); + +int +qux (int u, int v, int w, int x, int y) +{ + [[gnu::musttail]] return baz (u, v, w, x, y + 1); /* { dg-error "cannot tail-call: target is not able to optimize the call into a sibling call" } */ +} + +extern int corge (int, int, int, int, unsigned short); + +int +garply (int u, int v, int w, int x, unsigned short y) +{ + [[gnu::musttail]] return corge (u, v, w, x, y + 1); /* { dg-error "cannot tail-call: target is not able to optimize the call into a sibling call" } */ +} diff --git a/gcc/testsuite/gcc.target/s390/pr119873-5.c b/gcc/testsuite/gcc.target/s390/pr119873-5.c new file mode 100644 index 0000000..b5a7950 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr119873-5.c @@ -0,0 +1,11 @@ +/* PR target/119873 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -m31 -mzarch" } */ + +extern void foo (int x, int y, int z, long long w, int v); + +void +bar (int x, int y, int z, long long w, int v) +{ + [[gnu::musttail]] return foo (x, y, z, w, v); +} diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_52.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_52.f90 index cb7cf70..421d247 100644 --- a/gcc/testsuite/gfortran.dg/proc_ptr_52.f90 +++ b/gcc/testsuite/gfortran.dg/proc_ptr_52.f90 @@ -1,4 +1,5 @@ ! { dg-do run } +! { dg-additional-options "-fcheck=pointer" } ! ! Test the fix for PRs93924 & 93925. ! diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_57.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_57.f90 new file mode 100644 index 0000000..7ecb88f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/proc_ptr_57.f90 @@ -0,0 +1,36 @@ +! { dg-do compile } +! { dg-additional-options "-fcheck=pointer" } +! +! PR fortran/102900 + +module cs + implicit none + interface + function classStar_map_ifc() result(y) + import + class(*), pointer :: y + end function classStar_map_ifc + end interface + +contains + + function selector() + procedure(classStar_map_ifc), pointer :: selector + selector => NULL() + end function selector + + function selector_result() result(f) + procedure(classStar_map_ifc), pointer :: f + f => NULL() + end function selector_result + + function fun(x) result(y) + class(*), pointer :: y + class(*), target, intent(in) :: x + select type (x) + class default + y => null() + end select + end function fun + +end module cs diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index a194bf6..e27166c 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -54,7 +54,6 @@ along with GCC; see the file COPYING3. If not see #include "dbgcnt.h" #include "tree-ssa-propagate.h" #include "tree-ssa-dce.h" -#include "calls.h" #include "tree-ssa-loop-niter.h" /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */ diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 353227a..775b000 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,9 @@ +2025-04-24 Jakub Jelinek <jakub@redhat.com> + + PR c++/110343 + * lex.cc (lex_raw_string): For C allow $@` in raw string delimiters + if CPP_OPTION (pfile, low_ucns) i.e. for C23 and later. + 2025-04-09 Jakub Jelinek <jakub@redhat.com> PR preprocessor/118674 diff --git a/libgcc/config/gcn/crt0.c b/libgcc/config/gcn/crt0.c index dbd6749..cc23e21 100644 --- a/libgcc/config/gcn/crt0.c +++ b/libgcc/config/gcn/crt0.c @@ -24,6 +24,28 @@ typedef long long size_t; /* Provide an entry point symbol to silence a linker warning. */ void _start() {} + +#define PR119369_fixed 0 + + +/* Host/device compatibility: '__cxa_finalize'. Dummy; if necessary, + overridden via libgomp 'target-cxa-dso-dtor.c'. */ + +#if PR119369_fixed +extern void __GCC_offload___cxa_finalize (void *) __attribute__((weak)); +#else +void __GCC_offload___cxa_finalize (void *) __attribute__((weak)); + +void __attribute__((weak)) +__GCC_offload___cxa_finalize (void *dso_handle __attribute__((unused))) +{ +} +#endif + +/* There are no DSOs; this is the main program. */ +static void * const __dso_handle = 0; + + #ifdef USE_NEWLIB_INITFINI extern void __libc_init_array (void) __attribute__((weak)); @@ -38,6 +60,11 @@ void _init_array() __attribute__((amdgpu_hsa_kernel ())) void _fini_array() { +#if PR119369_fixed + if (__GCC_offload___cxa_finalize) +#endif + __GCC_offload___cxa_finalize (__dso_handle); + __libc_fini_array (); } @@ -70,6 +97,11 @@ void _init_array() __attribute__((amdgpu_hsa_kernel ())) void _fini_array() { +#if PR119369_fixed + if (__GCC_offload___cxa_finalize) +#endif + __GCC_offload___cxa_finalize (__dso_handle); + size_t count; size_t i; diff --git a/libgcc/config/nvptx/gbl-ctors.c b/libgcc/config/nvptx/gbl-ctors.c index 2626811..10954ee 100644 --- a/libgcc/config/nvptx/gbl-ctors.c +++ b/libgcc/config/nvptx/gbl-ctors.c @@ -31,6 +31,20 @@ extern int atexit (void (*function) (void)); +/* Host/device compatibility: '__cxa_finalize'. Dummy; if necessary, + overridden via libgomp 'target-cxa-dso-dtor.c'. */ + +extern void __GCC_offload___cxa_finalize (void *); + +void __attribute__((weak)) +__GCC_offload___cxa_finalize (void *dso_handle __attribute__((unused))) +{ +} + +/* There are no DSOs; this is the main program. */ +static void * const __dso_handle = 0; + + /* Handler functions ('static', in contrast to the 'gbl-ctors.h' prototypes). */ @@ -49,6 +63,8 @@ static void __static_do_global_dtors (void); static void __static_do_global_dtors (void) { + __GCC_offload___cxa_finalize (__dso_handle); + func_ptr *p = __DTOR_LIST__; ++p; for (; *p; ++p) diff --git a/libgm2/ChangeLog b/libgm2/ChangeLog index fb9920e..51a8e38 100644 --- a/libgm2/ChangeLog +++ b/libgm2/ChangeLog @@ -1,3 +1,44 @@ +2025-04-24 Gaius Mulley <gaiusmod2@gmail.com> + + PR modula2/115276 + * config.h.in: Regenerate. + * configure: Regenerate. + * configure.ac (AC_STRUCT_TIMEZONE): Add. + (AC_CHECK_MEMBER): Test for struct tm.tm_year. + (AC_CHECK_MEMBER): Test for struct tm.tm_mon. + (AC_CHECK_MEMBER): Test for struct tm.tm_mday. + (AC_CHECK_MEMBER): Test for struct tm.tm_hour. + (AC_CHECK_MEMBER): Test for struct tm.tm_min. + (AC_CHECK_MEMBER): Test for struct tm.tm_sec. + (AC_CHECK_MEMBER): Test for struct tm.tm_year. + (AC_CHECK_MEMBER): Test for struct tm.tm_yday. + (AC_CHECK_MEMBER): Test for struct tm.tm_wday. + (AC_CHECK_MEMBER): Test for struct tm.tm_isdst. + (AC_CHECK_MEMBER): Test for struct timeval.tv_sec. + (AC_CHECK_MEMBER): Test for struct timeval.tv_sec. + (AC_CHECK_MEMBER): Test for struct timeval.tv_usec. + * libm2iso/wraptime.cc (InitTimeval): Guard against lack + struct timeval and malloc. + (InitTimezone): Guard against lack of struct tm.tm_zone + and malloc. + (KillTimezone): Ditto. + (InitTimeval): Guard against lack of struct timeval + and malloc. + (KillTimeval): Guard against lack of malloc. + (settimeofday): Guard against lack of struct tm.tm_zone. + (GetFractions): Guard against lack of struct timeval. + (localtime_r): Ditto. + (GetYear): Guard against lack of struct tm. + (GetMonth): Ditto. + (GetDay): Ditto. + (GetHour): Ditto. + (GetMinute): Ditto. + (GetSecond): Ditto. + (GetSummerTime): Ditto. + (GetDST): Guards against lack of struct timezone. + (SetTimezone): Ditto. + (SetTimeval): Guard against lack of struct tm. + 2025-03-28 Gaius Mulley <gaiusmod2@gmail.com> PR modula2/118045 diff --git a/libgm2/config.h.in b/libgm2/config.h.in index 321ef3b..f9710ff 100644 --- a/libgm2/config.h.in +++ b/libgm2/config.h.in @@ -34,6 +34,10 @@ */ #undef HAVE_DECL_GETENV +/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. + */ +#undef HAVE_DECL_TZNAME + /* Define to 1 if you have the <direct.h> header file. */ #undef HAVE_DIRECT_H @@ -232,6 +236,9 @@ /* Define to 1 if the system has the type `struct tm'. */ #undef HAVE_STRUCT_TM +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ +#undef HAVE_STRUCT_TM_TM_ZONE + /* Define to 1 if you have the <sys/errno.h> header file. */ #undef HAVE_SYS_ERRNO_H @@ -286,6 +293,10 @@ /* Define if struct tm has a tm_gmtoff field. */ #undef HAVE_TM_TM_GMTOFF +/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use + `HAVE_STRUCT_TM_TM_ZONE' instead. */ +#undef HAVE_TM_ZONE + /* function tzname exists */ #undef HAVE_TZNAME @@ -338,6 +349,9 @@ /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ #undef TIME_WITH_SYS_TIME +/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +#undef TM_IN_SYS_TIME + /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE @@ -363,6 +377,45 @@ /* Version number of package */ #undef VERSION +/* struct timeval was found */ +#undef WE_HAVE_STRUCT_TIMEVAL + +/* struct timeval.tv_sec was found */ +#undef WE_HAVE_STRUCT_TIMEVAL_TV_SEC + +/* struct timeval.tv_usec was found */ +#undef WE_HAVE_STRUCT_TIMEVAL_TV_USEC + +/* struct tm was found */ +#undef WE_HAVE_STRUCT_TM + +/* struct tm.tm_hour was found */ +#undef WE_HAVE_STRUCT_TM_HOUR + +/* struct tm.tm_isdst was found */ +#undef WE_HAVE_STRUCT_TM_ISDST + +/* struct tm.tm_mday was found */ +#undef WE_HAVE_STRUCT_TM_MDAY + +/* struct tm.tm_min was found */ +#undef WE_HAVE_STRUCT_TM_MIN + +/* struct tm.tm_mon was found */ +#undef WE_HAVE_STRUCT_TM_MON + +/* struct tm.tm_sec was found */ +#undef WE_HAVE_STRUCT_TM_SEC + +/* struct tm.tm_wday was found */ +#undef WE_HAVE_STRUCT_TM_WDAY + +/* struct tm.tm_yday was found */ +#undef WE_HAVE_STRUCT_TM_YDAY + +/* struct tm.tm_year was found */ +#undef WE_HAVE_STRUCT_TM_YEAR + /* Defined if no way to sleep is available. */ #undef _GLIBCXX_NO_SLEEP diff --git a/libgm2/configure b/libgm2/configure index efe3b66..8ffdb31 100755 --- a/libgm2/configure +++ b/libgm2/configure @@ -2100,6 +2100,109 @@ $as_echo "$ac_res" >&6; } } # ac_fn_cxx_check_func +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -2269,52 +2372,6 @@ $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type - -# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES -# --------------------------------------------- -# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. -ac_fn_c_check_decl () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - as_decl_name=`echo $2|sed 's/ *(.*//'` - as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -$as_echo_n "checking whether $as_decl_name is declared... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -#ifndef $as_decl_name -#ifdef __cplusplus - (void) $as_decl_use; -#else - (void) $as_decl_name; -#endif -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_decl cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. @@ -6872,6 +6929,7 @@ $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi + ac_fn_c_check_header_mongrel "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default" if test "x$ac_cv_header_math_h" = xyes; then : @@ -6903,6 +6961,223 @@ fi done +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if ${ac_cv_struct_tm+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <time.h> + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h +else + ac_cv_struct_tm=sys/time.h +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include <sys/types.h> +#include <$ac_cv_struct_tm> + +" +if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_TM_TM_ZONE 1 +_ACEOF + + +fi + +if test "$ac_cv_member_struct_tm_tm_zone" = yes; then + +$as_echo "#define HAVE_TM_ZONE 1" >>confdefs.h + +else + ac_fn_c_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include <time.h> +" +if test "x$ac_cv_have_decl_tzname" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_TZNAME $ac_have_decl +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5 +$as_echo_n "checking for tzname... " >&6; } +if ${ac_cv_var_tzname+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test x$gcc_no_link = xyes; then + as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5 +fi +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <time.h> +#if !HAVE_DECL_TZNAME +extern char *tzname[]; +#endif + +int +main () +{ +return tzname[0][0]; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_var_tzname=yes +else + ac_cv_var_tzname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5 +$as_echo "$ac_cv_var_tzname" >&6; } + if test $ac_cv_var_tzname = yes; then + +$as_echo "#define HAVE_TZNAME 1" >>confdefs.h + + fi +fi + + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_year" "ac_cv_member_struct_tm_tm_year" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_year" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_year" "ac_cv_member_struct_tm_tm_year" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_year" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_YEAR 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_mon" "ac_cv_member_struct_tm_tm_mon" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_mon" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_MON 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_mday" "ac_cv_member_struct_tm_tm_mday" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_mday" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_MDAY 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_hour" "ac_cv_member_struct_tm_tm_hour" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_hour" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_HOUR 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_min" "ac_cv_member_struct_tm_tm_min" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_min" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_MIN 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_sec" "ac_cv_member_struct_tm_tm_sec" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_sec" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_SEC 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_year" "ac_cv_member_struct_tm_tm_year" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_year" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_YEAR 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_yday" "ac_cv_member_struct_tm_tm_yday" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_yday" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_YDAY 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_wday" "ac_cv_member_struct_tm_tm_wday" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_wday" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_WDAY 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct tm" "tm_isdst" "ac_cv_member_struct_tm_tm_isdst" "#include <time.h> +" +if test "x$ac_cv_member_struct_tm_tm_isdst" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TM_ISDST 1" >>confdefs.h + +fi + + +ac_fn_c_check_member "$LINENO" "struct timeval" "tv_sec" "ac_cv_member_struct_timeval_tv_sec" "$ac_includes_default" +if test "x$ac_cv_member_struct_timeval_tv_sec" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TIMEVAL 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct timeval" "tv_sec" "ac_cv_member_struct_timeval_tv_sec" "$ac_includes_default" +if test "x$ac_cv_member_struct_timeval_tv_sec" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TIMEVAL_TV_SEC 1" >>confdefs.h + +fi + +ac_fn_c_check_member "$LINENO" "struct timeval" "tv_usec" "ac_cv_member_struct_timeval_tv_usec" "$ac_includes_default" +if test "x$ac_cv_member_struct_timeval_tv_usec" = xyes; then : + +$as_echo "#define WE_HAVE_STRUCT_TIMEVAL_TV_USEC 1" >>confdefs.h + +fi + + case ${build_alias} in "") build_noncanonical=${build} ;; @@ -14579,7 +14854,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 14582 "configure" +#line 14857 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14685,7 +14960,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 14688 "configure" +#line 14963 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/libgm2/configure.ac b/libgm2/configure.ac index c070491..437485f 100644 --- a/libgm2/configure.ac +++ b/libgm2/configure.ac @@ -89,6 +89,7 @@ AC_ARG_WITH(cross-host, AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_HEADER_TIME + AC_CHECK_HEADER([math.h], [AC_DEFINE([HAVE_MATH_H], [1], [have math.h])]) @@ -102,6 +103,49 @@ AC_CHECK_HEADERS(getopt.h limits.h stddef.h string.h strings.h \ pthread.h stdarg.h stdio.h sys/types.h termios.h \ netinet/in.h netdb.h sys/uio.h sys/stat.h wchar.h) +AC_STRUCT_TIMEZONE + +AC_CHECK_MEMBER([struct tm.tm_year], + [AC_DEFINE(WE_HAVE_STRUCT_TM, [1], [struct tm was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_year], + [AC_DEFINE(WE_HAVE_STRUCT_TM_YEAR, [1], [struct tm.tm_year was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_mon], + [AC_DEFINE(WE_HAVE_STRUCT_TM_MON, [1], [struct tm.tm_mon was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_mday], + [AC_DEFINE(WE_HAVE_STRUCT_TM_MDAY, [1], [struct tm.tm_mday was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_hour], + [AC_DEFINE(WE_HAVE_STRUCT_TM_HOUR, [1], [struct tm.tm_hour was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_min], + [AC_DEFINE(WE_HAVE_STRUCT_TM_MIN, [1], [struct tm.tm_min was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_sec], + [AC_DEFINE(WE_HAVE_STRUCT_TM_SEC, [1], [struct tm.tm_sec was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_year], + [AC_DEFINE(WE_HAVE_STRUCT_TM_YEAR, [1], [struct tm.tm_year was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_yday], + [AC_DEFINE(WE_HAVE_STRUCT_TM_YDAY, [1], [struct tm.tm_yday was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_wday], + [AC_DEFINE(WE_HAVE_STRUCT_TM_WDAY, [1], [struct tm.tm_wday was found])], + [], [[#include <time.h>]]) +AC_CHECK_MEMBER([struct tm.tm_isdst], + [AC_DEFINE(WE_HAVE_STRUCT_TM_ISDST, [1], [struct tm.tm_isdst was found])], + [], [[#include <time.h>]]) + +AC_CHECK_MEMBER([struct timeval.tv_sec], + [AC_DEFINE(WE_HAVE_STRUCT_TIMEVAL, [1], [struct timeval was found])]) +AC_CHECK_MEMBER([struct timeval.tv_sec], + [AC_DEFINE(WE_HAVE_STRUCT_TIMEVAL_TV_SEC, [1], [struct timeval.tv_sec was found])]) +AC_CHECK_MEMBER([struct timeval.tv_usec], + [AC_DEFINE(WE_HAVE_STRUCT_TIMEVAL_TV_USEC, [1], [struct timeval.tv_usec was found])]) + AC_CANONICAL_HOST ACX_NONCANONICAL_HOST ACX_NONCANONICAL_TARGET diff --git a/libgm2/libm2iso/wraptime.cc b/libgm2/libm2iso/wraptime.cc index 4bbd5f9..ed5f05e 100644 --- a/libgm2/libm2iso/wraptime.cc +++ b/libgm2/libm2iso/wraptime.cc @@ -58,7 +58,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* InitTimeval returns a newly created opaque type. */ -#if defined(HAVE_STRUCT_TIMEVAL) && defined(HAVE_MALLOC_H) +#if defined(WE_HAVE_STRUCT_TIMEVAL) && defined(HAVE_MALLOC_H) extern "C" struct timeval * EXPORT(InitTimeval) (void) { @@ -85,7 +85,7 @@ EXPORT(KillTimeval) (void *tv) /* InitTimezone returns a newly created opaque type. */ -#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_MALLOC_H) +#if defined(HAVE_STRUCT_TM_TM_ZONE) && defined(HAVE_MALLOC_H) extern "C" struct timezone * EXPORT(InitTimezone) (void) { @@ -102,14 +102,20 @@ EXPORT(InitTimezone) (void) /* KillTimezone - deallocates the memory associated with an opaque type. */ +#if defined(HAVE_STRUCT_TM_TM_ZONE) && defined(HAVE_MALLOC_H) extern "C" struct timezone * EXPORT(KillTimezone) (struct timezone *tv) { -#if defined(HAVE_MALLOC_H) free (tv); -#endif return NULL; } +#else +extern "C" void * +EXPORT(KillTimezone) (void *tv) +{ + return NULL; +} +#endif /* InitTM - returns a newly created opaque type. */ @@ -141,7 +147,7 @@ EXPORT(KillTM) (struct tm *tv) /* gettimeofday - calls gettimeofday(2) with the same parameters, tv, and, tz. It returns 0 on success. */ -#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_GETTIMEOFDAY) +#if defined(HAVE_STRUCT_TM_TM_ZONE) && defined(HAVE_GETTIMEOFDAY) extern "C" int EXPORT(gettimeofday) (void *tv, struct timezone *tz) { @@ -158,7 +164,7 @@ EXPORT(gettimeofday) (void *tv, void *tz) /* settimeofday - calls settimeofday(2) with the same parameters, tv, and, tz. It returns 0 on success. */ -#if defined(HAVE_STRUCT_TIMEZONE) && defined(HAVE_SETTIMEOFDAY) +#if defined(HAVE_STRUCT_TM_TM_ZONE) && defined(HAVE_SETTIMEOFDAY) extern "C" int EXPORT(settimeofday) (void *tv, struct timezone *tz) { @@ -175,7 +181,7 @@ EXPORT(settimeofday) (void *tv, void *tz) /* wraptime_GetFractions - returns the tv_usec field inside the timeval structure. */ -#if defined(HAVE_STRUCT_TIMEVAL) +#if defined(WE_HAVE_STRUCT_TIMEVAL_TV_USEC) extern "C" unsigned int EXPORT(GetFractions) (struct timeval *tv) { @@ -194,7 +200,7 @@ EXPORT(GetFractions) (void *tv) this procedure function expects, timeval, as its first parameter and not a time_t (as expected by the posix equivalent). */ -#if defined(HAVE_STRUCT_TIMEVAL) +#if defined(WE_HAVE_STRUCT_TIMEVAL_TV_SEC) extern "C" struct tm * EXPORT(localtime_r) (struct timeval *tv, struct tm *m) { @@ -210,7 +216,7 @@ EXPORT(localtime_r) (void *tv, struct tm *m) /* wraptime_GetYear - returns the year from the structure, m. */ -#if defined(HAVE_STRUCT_TM) +#if defined(WE_HAVE_STRUCT_TM_YEAR) extern "C" unsigned int EXPORT(GetYear) (struct tm *m) { @@ -226,7 +232,7 @@ EXPORT(GetYear) (void *m) /* wraptime_GetMonth - returns the month from the structure, m. */ -#if defined(HAVE_STRUCT_TM) +#if defined(WE_HAVE_STRUCT_TM_MON) extern "C" unsigned int EXPORT(GetMonth) (struct tm *m) { @@ -243,7 +249,7 @@ EXPORT(GetMonth) (void *m) /* wraptime_GetDay - returns the day of the month from the structure, m. */ -#if defined(HAVE_STRUCT_TM) +#if defined(WE_HAVE_STRUCT_TM_MDAY) extern "C" unsigned int EXPORT(GetDay) (struct tm *m) { @@ -260,7 +266,7 @@ EXPORT(GetDay) (void *m) /* wraptime_GetHour - returns the hour of the day from the structure, m. */ -#if defined(HAVE_STRUCT_TM) +#if defined(WE_HAVE_STRUCT_TM_HOUR) extern "C" unsigned int EXPORT(GetHour) (struct tm *m) { @@ -277,7 +283,7 @@ EXPORT(GetHour) (void *m) /* wraptime_GetMinute - returns the minute within the hour from the structure, m. */ -#if defined(HAVE_STRUCT_TM) +#if defined(WE_HAVE_STRUCT_TM_MIN) extern "C" unsigned int EXPORT(GetMinute) (struct tm *m) { @@ -295,7 +301,7 @@ EXPORT(GetMinute) (void *m) structure, m. The return value will always be in the range 0..59. A leap minute of value 60 will be truncated to 59. */ -#if defined(HAVE_STRUCT_TM) +#if defined(WE_HAVE_STRUCT_TM_SEC) extern "C" unsigned int EXPORT(GetSecond) (struct tm *m) { @@ -314,7 +320,7 @@ EXPORT(GetSecond) (void *m) /* wraptime_GetSummerTime - returns true if summer time is in effect. */ -#if defined(HAVE_STRUCT_TIMEZONE) +#if defined(HAVE_STRUCT_TM_TM_ZONE) extern "C" bool EXPORT(GetSummerTime) (struct timezone *tz) { @@ -330,7 +336,7 @@ EXPORT(GetSummerTime) (void *tz) /* wraptime_GetDST - returns the number of minutes west of GMT. */ -#if defined(HAVE_STRUCT_TIMEZONE) +#if defined(HAVE_STRUCT_TM_TM_ZONE) extern "C" int EXPORT(GetDST) (struct timezone *tz) { @@ -350,7 +356,7 @@ EXPORT(GetDST) (void *tz) /* SetTimezone - set the timezone field inside timeval, tv. */ -#if defined(HAVE_STRUCT_TIMEZONE) +#if defined(HAVE_STRUCT_TM_TM_ZONE) extern "C" void EXPORT(SetTimezone) (struct timezone *tz, int zone, int minuteswest) { @@ -367,22 +373,40 @@ EXPORT(SetTimezone) (void *tz, int zone, int minuteswest) /* SetTimeval - sets the fields in tm, t, with: second, minute, hour, day, month, year, fractions. */ -#if defined(HAVE_STRUCT_TIMEVAL) +#if defined(WE_HAVE_STRUCT_TM) extern "C" void EXPORT(SetTimeval) (struct tm *t, unsigned int second, unsigned int minute, unsigned int hour, unsigned int day, unsigned int month, unsigned int year, unsigned int yday, unsigned int wday, unsigned int isdst) { +#if defined(WE_HAVE_STRUCT_TM_SEC) t->tm_sec = second; +#endif +#if defined(WE_HAVE_STRUCT_TM_MIN) t->tm_min = minute; +#endif +#if defined(WE_HAVE_STRUCT_TM_HOUR) t->tm_hour = hour; +#endif +#if defined(WE_HAVE_STRUCT_TM_MDAY) t->tm_mday = day; +#endif +#if defined(WE_HAVE_STRUCT_TM_MON) t->tm_mon = month; +#endif +#if defined(WE_HAVE_STRUCT_TM_YEAR) t->tm_year = year; +#endif +#if defined(WE_HAVE_STRUCT_TM_YDAY) t->tm_yday = yday; +#endif +#if defined(WE_HAVE_STRUCT_TM_WDAY) t->tm_wday = wday; +#endif +#if defined(WE_HAVE_STRUCT_TM_ISDST) t->tm_isdst = isdst; +#endif } #else extern "C" void diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index 096e17b..49a62d4 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,53 @@ +2025-04-24 Tobias Burnus <tburnus@baylibre.com> + + * testsuite/lib/libgomp.exp + (check_effective_target_gomp_hip_header_nvidia): Compile with + "-Wno-deprecated-declarations". + * testsuite/libgomp.c/interop-hip-nvidia-full.c: Likewise. + * testsuite/libgomp.c/interop-hipblas-nvidia-full.c: Likewise. + * testsuite/libgomp.c/interop-hipblas.h: Add workarounds + when using the HIP headers with __HIP_PLATFORM_NVIDIA__. + +2025-04-24 Tobias Burnus <tburnus@baylibre.com> + + * testsuite/lib/libgomp.exp (check_effective_target_openacc_cublas, + check_effective_target_openacc_cudart): Update description as + the check requires more. + (check_effective_target_openacc_libcuda, + check_effective_target_openacc_libcublas, + check_effective_target_openacc_libcudart, + check_effective_target_gomp_hip_header_amd, + check_effective_target_gomp_hip_header_nvidia, + check_effective_target_gomp_hipfort_module, + check_effective_target_gomp_libamdhip64, + check_effective_target_gomp_libhipblas): New. + * testsuite/libgomp.c-c++-common/interop-2.c: New test. + * testsuite/libgomp.c/interop-cublas-full.c: New test. + * testsuite/libgomp.c/interop-cublas-libonly.c: New test. + * testsuite/libgomp.c/interop-cuda-full.c: New test. + * testsuite/libgomp.c/interop-cuda-libonly.c: New test. + * testsuite/libgomp.c/interop-hip-amd-full.c: New test. + * testsuite/libgomp.c/interop-hip-amd-no-hip-header.c: New test. + * testsuite/libgomp.c/interop-hip-nvidia-full.c: New test. + * testsuite/libgomp.c/interop-hip-nvidia-no-headers.c: New test. + * testsuite/libgomp.c/interop-hip-nvidia-no-hip-header.c: New test. + * testsuite/libgomp.c/interop-hip.h: New test. + * testsuite/libgomp.c/interop-hipblas-amd-full.c: New test. + * testsuite/libgomp.c/interop-hipblas-amd-no-hip-header.c: New test. + * testsuite/libgomp.c/interop-hipblas-nvidia-full.c: New test. + * testsuite/libgomp.c/interop-hipblas-nvidia-no-headers.c: New test. + * testsuite/libgomp.c/interop-hipblas-nvidia-no-hip-header.c: New test. + * testsuite/libgomp.c/interop-hipblas.h: New test. + * testsuite/libgomp.fortran/interop-hip-amd-full.F90: New test. + * testsuite/libgomp.fortran/interop-hip-amd-no-module.F90: New test. + * testsuite/libgomp.fortran/interop-hip-nvidia-full.F90: New test. + * testsuite/libgomp.fortran/interop-hip-nvidia-no-module.F90: New test. + * testsuite/libgomp.fortran/interop-hip.h: New test. + +2025-04-23 Tobias Burnus <tburnus@baylibre.com> + + * testsuite/libgomp.fortran/target-enter-data-8.f90: New test. + 2025-04-17 Jakub Jelinek <jakub@redhat.com> PR libgomp/119849 diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am index e3202ae..19479ae 100644 --- a/libgomp/Makefile.am +++ b/libgomp/Makefile.am @@ -70,7 +70,7 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c error.c \ target.c splay-tree.c libgomp-plugin.c oacc-parallel.c oacc-host.c \ oacc-init.c oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c \ priority_queue.c affinity-fmt.c teams.c allocator.c oacc-profiling.c \ - oacc-target.c target-indirect.c + oacc-target.c target-indirect.c target-cxa-dso-dtor.c include $(top_srcdir)/plugin/Makefrag.am diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in index 2a0a842..6d22b3d 100644 --- a/libgomp/Makefile.in +++ b/libgomp/Makefile.in @@ -219,7 +219,8 @@ am_libgomp_la_OBJECTS = alloc.lo atomic.lo barrier.lo critical.lo \ oacc-parallel.lo oacc-host.lo oacc-init.lo oacc-mem.lo \ oacc-async.lo oacc-plugin.lo oacc-cuda.lo priority_queue.lo \ affinity-fmt.lo teams.lo allocator.lo oacc-profiling.lo \ - oacc-target.lo target-indirect.lo $(am__objects_1) + oacc-target.lo target-indirect.lo target-cxa-dso-dtor.lo \ + $(am__objects_1) libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -552,7 +553,8 @@ libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c \ oacc-parallel.c oacc-host.c oacc-init.c oacc-mem.c \ oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \ affinity-fmt.c teams.c allocator.c oacc-profiling.c \ - oacc-target.c target-indirect.c $(am__append_3) + oacc-target.c target-indirect.c target-cxa-dso-dtor.c \ + $(am__append_3) # Nvidia PTX OpenACC plugin. @PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info $(libtool_VERSION) @@ -780,6 +782,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/single.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay-tree.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target-cxa-dso-dtor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target-indirect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/target.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task.Plo@am__quote@ diff --git a/libgomp/config/accel/target-cxa-dso-dtor.c b/libgomp/config/accel/target-cxa-dso-dtor.c new file mode 100644 index 0000000..e40a5f0 --- /dev/null +++ b/libgomp/config/accel/target-cxa-dso-dtor.c @@ -0,0 +1,62 @@ +/* Host/device compatibility: Itanium C++ ABI, DSO Object Destruction API + + Copyright (C) 2025 Free Software Foundation, Inc. + + This file is part of the GNU Offloading and Multi Processing Library + (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "libgomp.h" + +extern void __cxa_finalize (void *); + +/* See <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#dso-dtor>. + + Even if the device is '!DEFAULT_USE_CXA_ATEXIT', we may see '__cxa_atexit' + calls, referencing '__dso_handle', via a 'DEFAULT_USE_CXA_ATEXIT' host. + '__cxa_atexit' is provided by newlib, but use of '__dso_handle' for nvptx + results in 'ld' error: + + unresolved symbol __dso_handle + collect2: error: ld returned 1 exit status + nvptx mkoffload: fatal error: [...]/x86_64-pc-linux-gnu-accel-nvptx-none-gcc returned 1 exit status + + ..., or for GCN get an implicit definition (running with + '--trace-symbol=__dso_handle'): + + ./a.xamdgcn-amdhsa.mkoffload.hsaco-a.xamdgcn-amdhsa.mkoffload.2.o: reference to __dso_handle + <internal>: definition of __dso_handle + + ..., which might be fine, but let's just make it explicit. */ + +/* There are no DSOs; this is the main program. */ +attribute_hidden void * const __dso_handle = 0; + +/* If this file gets linked in, that means that '__dso_handle' has been + referenced (for '__cxa_atexit'), and in that case, we also have to run + '__cxa_finalize'. Make that happen by overriding the weak libgcc dummy + function '__GCC_offload___cxa_finalize'. */ + +void +__GCC_offload___cxa_finalize (void *dso_handle) +{ + __cxa_finalize (dso_handle); +} diff --git a/libgomp/target-cxa-dso-dtor.c b/libgomp/target-cxa-dso-dtor.c new file mode 100644 index 0000000..d1a898d --- /dev/null +++ b/libgomp/target-cxa-dso-dtor.c @@ -0,0 +1,3 @@ +/* Host/device compatibility: Itanium C++ ABI, DSO Object Destruction API */ + +/* Nothing needed here. */ diff --git a/libgomp/testsuite/libgomp.c++/target-cdtor-1.C b/libgomp/testsuite/libgomp.c++/target-cdtor-1.C new file mode 100644 index 0000000..ecb029e --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/target-cdtor-1.C @@ -0,0 +1,104 @@ +/* Offloaded C++ objects construction and destruction. */ + +/* { dg-additional-options -fdump-tree-optimized-raw-asmname } + { dg-additional-options -foffload-options=-fdump-tree-optimized-raw-asmname } */ + +#include <omp.h> +#include <vector> + +#pragma omp declare target + +struct S +{ + int x; + + S() + : x(-1) + { + __builtin_printf("%s, %d, %d\n", __FUNCTION__, x, omp_is_initial_device()); + } + S(int x) + : x(x) + { + __builtin_printf("%s, %d, %d\n", __FUNCTION__, x, omp_is_initial_device()); + } + ~S() + { + __builtin_printf("%s, %d, %d\n", __FUNCTION__, x, omp_is_initial_device()); + } +}; + +#pragma omp end declare target + +S sH1(7); + +#pragma omp declare target + +S sHD1(5); + +std::vector<S> svHD1(2); + +#pragma omp end declare target + +S sH2(3); + +int main() +{ + int c = 0; + + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + +#pragma omp target map(c) + { + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + } + +#pragma omp target map(c) + { + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + } + + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + + return 0; +} + +/* Verify '__cxa_atexit' calls. + + For the host, there are four expected calls: + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, } 4 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZNSt6vectorI1SSaIS0_EED1Ev, \&svHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH2, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + + For the device, there are two expected calls: + { dg-final { scan-offload-tree-dump-times {gimple_call <__cxa_atexit, } 2 optimized { target cxa_atexit } } } + { dg-final { scan-offload-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-offload-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZNSt6vectorI1SSaIS0_EED1Ev, \&svHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } +*/ + +/* C++ objects are constructed in order of appearance (..., and destructed in reverse order). + { dg-output {S, 7, 1[\r\n]+} } + { dg-output {S, 5, 1[\r\n]+} } + { dg-output {S, -1, 1[\r\n]+} } + { dg-output {S, -1, 1[\r\n]+} } + { dg-output {S, 3, 1[\r\n]+} } + { dg-output {main:1, 1[\r\n]+} } + { dg-output {S, 5, 0[\r\n]+} { target offload_device } } + { dg-output {S, -1, 0[\r\n]+} { target offload_device } } + { dg-output {S, -1, 0[\r\n]+} { target offload_device } } + { dg-output {main:2, 1[\r\n]+} { target { ! offload_device } } } + { dg-output {main:2, 0[\r\n]+} { target offload_device } } + { dg-output {main:3, 1[\r\n]+} { target { ! offload_device } } } + { dg-output {main:3, 0[\r\n]+} { target offload_device } } + { dg-output {main:4, 1[\r\n]+} } + { dg-output {~S, -1, 0[\r\n]+} { target offload_device } } + { dg-output {~S, -1, 0[\r\n]+} { target offload_device } } + { dg-output {~S, 5, 0[\r\n]+} { target offload_device } } + { dg-output {~S, 3, 1[\r\n]+} } + { dg-output {~S, -1, 1[\r\n]+} } + { dg-output {~S, -1, 1[\r\n]+} } + { dg-output {~S, 5, 1[\r\n]+} } + { dg-output {~S, 7, 1[\r\n]+} } +*/ diff --git a/libgomp/testsuite/libgomp.c++/target-cdtor-2.C b/libgomp/testsuite/libgomp.c++/target-cdtor-2.C new file mode 100644 index 0000000..75e48ca --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/target-cdtor-2.C @@ -0,0 +1,140 @@ +/* Offloaded 'constructor' and 'destructor' functions, and C++ objects construction and destruction. */ + +/* { dg-require-effective-target init_priority } */ + +/* { dg-additional-options -fdump-tree-optimized-raw-asmname } + { dg-additional-options -foffload-options=-fdump-tree-optimized-raw-asmname } */ + +#include <omp.h> +#include <vector> + +#pragma omp declare target + +struct S +{ + int x; + + S() + : x(-1) + { + __builtin_printf("%s, %d, %d\n", __FUNCTION__, x, omp_is_initial_device()); + } + S(int x) + : x(x) + { + __builtin_printf("%s, %d, %d\n", __FUNCTION__, x, omp_is_initial_device()); + } + ~S() + { + __builtin_printf("%s, %d, %d\n", __FUNCTION__, x, omp_is_initial_device()); + } +}; + +#pragma omp end declare target + +S sH1 __attribute__((init_priority(1500))) (7); + +#pragma omp declare target + +S sHD1 __attribute__((init_priority(2000))) (5); + +std::vector<S> svHD1 __attribute__((init_priority(1000))) (2); + +static void +__attribute__((constructor(20000))) +initDH1() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +static void +__attribute__((destructor(20000))) +finiDH1() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +#pragma omp end declare target + +S sH2 __attribute__((init_priority(500))) (3); + +static void +__attribute__((constructor(10000))) +initH1() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +static void +__attribute__((destructor(10000))) +finiH1() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +int main() +{ + int c = 0; + + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + +#pragma omp target map(c) + { + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + } + +#pragma omp target map(c) + { + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + } + + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + + return 0; +} + +/* Verify '__cxa_atexit' calls. + + For the host, there are four expected calls: + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, } 4 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZNSt6vectorI1SSaIS0_EED1Ev, \&svHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sH2, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + + For the device, there are two expected calls: + { dg-final { scan-offload-tree-dump-times {gimple_call <__cxa_atexit, } 2 optimized { target cxa_atexit } } } + { dg-final { scan-offload-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZN1SD1Ev, \&sHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } + { dg-final { scan-offload-tree-dump-times {gimple_call <__cxa_atexit, NULL, _ZNSt6vectorI1SSaIS0_EED1Ev, \&svHD1, \&__dso_handle>} 1 optimized { target cxa_atexit } } } +*/ + +/* Defined order in which 'constructor' functions, and 'destructor' functions are run, and C++ objects are constructed (..., and destructed in reverse order). + { dg-output {S, 3, 1[\r\n]+} } + { dg-output {S, -1, 1[\r\n]+} } + { dg-output {S, -1, 1[\r\n]+} } + { dg-output {S, 7, 1[\r\n]+} } + { dg-output {S, 5, 1[\r\n]+} } + { dg-output {initH1, 1[\r\n]+} } + { dg-output {initDH1, 1[\r\n]+} } + { dg-output {main:1, 1[\r\n]+} } + { dg-output {S, -1, 0[\r\n]+} { target offload_device } } + { dg-output {S, -1, 0[\r\n]+} { target offload_device } } + { dg-output {S, 5, 0[\r\n]+} { target offload_device } } + { dg-output {initDH1, 0[\r\n]+} { target offload_device } } + { dg-output {main:2, 1[\r\n]+} { target { ! offload_device } } } + { dg-output {main:2, 0[\r\n]+} { target offload_device } } + { dg-output {main:3, 1[\r\n]+} { target { ! offload_device } } } + { dg-output {main:3, 0[\r\n]+} { target offload_device } } + { dg-output {main:4, 1[\r\n]+} } + { dg-output {~S, 5, 0[\r\n]+} { target offload_device } } + { dg-output {~S, -1, 0[\r\n]+} { target offload_device } } + { dg-output {~S, -1, 0[\r\n]+} { target offload_device } } + { dg-output {finiDH1, 0[\r\n]+} { target offload_device } } + { dg-output {~S, 5, 1[\r\n]+} } + { dg-output {~S, 7, 1[\r\n]+} } + { dg-output {~S, -1, 1[\r\n]+} } + { dg-output {~S, -1, 1[\r\n]+} } + { dg-output {~S, 3, 1[\r\n]+} } + { dg-output {finiDH1, 1[\r\n]+} } + { dg-output {finiH1, 1[\r\n]+} } +*/ diff --git a/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-GCN.C b/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-GCN.C index 3cdedf4..d4dccf1 100644 --- a/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-GCN.C +++ b/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-GCN.C @@ -14,8 +14,10 @@ /* In this specific C++ arrangement, distilled from PR118794, GCC synthesizes '__builtin_eh_pointer', '__builtin_unwind_resume' calls as dead code in 'f': - { dg-final { scan-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized } } - { dg-final { scan-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized } } + { dg-final { scan-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized { target { ! { arm_eabi || tic6x-*-* } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized { target { ! { arm_eabi || tic6x-*-* } } } } } + ..., just 'targetm.arm_eabi_unwinder' is different: + { dg-final { scan-tree-dump-times {gimple_call <__builtin_cxa_end_cleanup, } 1 optimized { target { arm_eabi || tic6x-*-* } } } } { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized } } { dg-final { only_for_offload_target amdgcn-amdhsa scan-offload-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized } } Given '-O0' and '-foffload-options=-mno-fake-exceptions', offload compilation fails: diff --git a/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-nvptx.C b/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-nvptx.C index ef996cf..724e34b 100644 --- a/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-nvptx.C +++ b/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-nvptx.C @@ -14,8 +14,10 @@ /* In this specific C++ arrangement, distilled from PR118794, GCC synthesizes '__builtin_eh_pointer', '__builtin_unwind_resume' calls as dead code in 'f': - { dg-final { scan-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized } } - { dg-final { scan-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized } } + { dg-final { scan-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized { target { ! { arm_eabi || tic6x-*-* } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized { target { ! { arm_eabi || tic6x-*-* } } } } } + ..., just 'targetm.arm_eabi_unwinder' is different: + { dg-final { scan-tree-dump-times {gimple_call <__builtin_cxa_end_cleanup, } 1 optimized { target { arm_eabi || tic6x-*-* } } } } { dg-final { only_for_offload_target nvptx-none scan-offload-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized } } { dg-final { only_for_offload_target nvptx-none scan-offload-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized } } Given '-O0' and '-foffload-options=-mno-fake-exceptions', offload compilation fails: diff --git a/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1.C b/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1.C index 24e3d07..24eb7a5 100644 --- a/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1.C +++ b/libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1.C @@ -51,7 +51,9 @@ int main() /* In this specific C++ arrangement, distilled from PR118794, GCC synthesizes '__builtin_eh_pointer', '__builtin_unwind_resume' calls as dead code in 'f': - { dg-final { scan-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized } } - { dg-final { scan-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized } } + { dg-final { scan-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized { target { ! { arm_eabi || tic6x-*-* } } } } } + { dg-final { scan-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized { target { ! { arm_eabi || tic6x-*-* } } } } } + ..., just 'targetm.arm_eabi_unwinder' is different: + { dg-final { scan-tree-dump-times {gimple_call <__builtin_cxa_end_cleanup, } 1 optimized { target { arm_eabi || tic6x-*-* } } } } { dg-final { scan-offload-tree-dump-times {gimple_call <__builtin_eh_pointer, } 1 optimized } } { dg-final { scan-offload-tree-dump-times {gimple_call <__builtin_unwind_resume, } 1 optimized } } */ diff --git a/libgomp/testsuite/libgomp.c++/target-exceptions-throw-1.C b/libgomp/testsuite/libgomp.c++/target-exceptions-throw-1.C index 2467061..a4e7a10 100644 --- a/libgomp/testsuite/libgomp.c++/target-exceptions-throw-1.C +++ b/libgomp/testsuite/libgomp.c++/target-exceptions-throw-1.C @@ -4,9 +4,6 @@ { dg-additional-options -fexceptions } */ /* { dg-additional-options -fdump-tree-optimized-raw } { dg-additional-options -foffload-options=-fdump-tree-optimized-raw } */ -/* { dg-bogus {Size expression must be absolute\.} PR119737 { target offload_target_amdgcn xfail *-*-* } 0 } - { dg-ice PR119737 { offload_target_amdgcn } } - { dg-excess-errors {'mkoffload' failures etc.} { xfail offload_target_amdgcn } } */ #include "../libgomp.oacc-c++/exceptions-throw-1.C" diff --git a/libgomp/testsuite/libgomp.c++/target-exceptions-throw-2.C b/libgomp/testsuite/libgomp.c++/target-exceptions-throw-2.C index e85e6c3..97f4845 100644 --- a/libgomp/testsuite/libgomp.c++/target-exceptions-throw-2.C +++ b/libgomp/testsuite/libgomp.c++/target-exceptions-throw-2.C @@ -4,9 +4,6 @@ { dg-additional-options -fexceptions } */ /* { dg-additional-options -fdump-tree-optimized-raw } { dg-additional-options -foffload-options=-fdump-tree-optimized-raw } */ -/* { dg-bogus {Size expression must be absolute\.} PR119737 { target offload_target_amdgcn xfail *-*-* } 0 } - { dg-ice PR119737 { offload_target_amdgcn } } - { dg-excess-errors {'mkoffload' failures etc.} { xfail offload_target_amdgcn } } */ #include "../libgomp.oacc-c++/exceptions-throw-2.C" diff --git a/libgomp/testsuite/libgomp.c-c++-common/target-cdtor-1.c b/libgomp/testsuite/libgomp.c-c++-common/target-cdtor-1.c new file mode 100644 index 0000000..e6099cf --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/target-cdtor-1.c @@ -0,0 +1,89 @@ +/* Offloaded 'constructor' and 'destructor' functions. */ + +#include <omp.h> + +#pragma omp declare target + +static void +__attribute__((constructor)) +initHD1() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +static void +__attribute__((constructor)) +initHD2() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +static void +__attribute__((destructor)) +finiHD1() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +static void +__attribute__((destructor)) +finiHD2() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +#pragma omp end declare target + +static void +__attribute__((constructor)) +initH1() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +static void +__attribute__((destructor)) +finiH2() +{ + __builtin_printf("%s, %d\n", __FUNCTION__, omp_is_initial_device()); +} + +int main() +{ + int c = 0; + + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + +#pragma omp target map(c) + { + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + } + +#pragma omp target map(c) + { + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + } + + __builtin_printf("%s:%d, %d\n", __FUNCTION__, ++c, omp_is_initial_device()); + + return 0; +} + +/* The order is undefined, in which same-priority 'constructor' functions, and 'destructor' functions are run. + { dg-output {init[^,]+, 1[\r\n]+} } + { dg-output {init[^,]+, 1[\r\n]+} } + { dg-output {init[^,]+, 1[\r\n]+} } + { dg-output {main:1, 1[\r\n]+} } + { dg-output {initHD[^,]+, 0[\r\n]+} { target offload_device } } + { dg-output {initHD[^,]+, 0[\r\n]+} { target offload_device } } + { dg-output {main:2, 1[\r\n]+} { target { ! offload_device } } } + { dg-output {main:2, 0[\r\n]+} { target offload_device } } + { dg-output {main:3, 1[\r\n]+} { target { ! offload_device } } } + { dg-output {main:3, 0[\r\n]+} { target offload_device } } + { dg-output {main:4, 1[\r\n]+} } + { dg-output {finiHD[^,]+, 0[\r\n]+} { target offload_device } } + { dg-output {finiHD[^,]+, 0[\r\n]+} { target offload_device } } + { dg-output {fini[^,]+, 1[\r\n]+} } + { dg-output {fini[^,]+, 1[\r\n]+} } + { dg-output {fini[^,]+, 1[\r\n]+} } +*/ diff --git a/libgomp/testsuite/libgomp.c/interop-hsa.c b/libgomp/testsuite/libgomp.c/interop-hsa.c new file mode 100644 index 0000000..cf8bc90 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/interop-hsa.c @@ -0,0 +1,203 @@ +/* { dg-additional-options "-ldl" } */ +/* { dg-require-effective-target offload_device_gcn } */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <omp.h> +#include <assert.h> +#include <dlfcn.h> +#include "../../../include/hsa.h" +#include "../../config/gcn/libgomp-gcn.h" + +#define STACKSIZE (100 * 1024) +#define HEAPSIZE (10 * 1024 * 1024) +#define ARENASIZE HEAPSIZE + +/* This code fragment must be optimized or else the host-fallback kernel has + * invalid ASM inserts. The rest of the file can be compiled safely at -O0. */ +#pragma omp declare target +uintptr_t __attribute__((optimize("O1"))) +get_kernel_ptr () +{ + uintptr_t val; + if (!omp_is_initial_device ()) + /* "main._omp_fn.0" is the name GCC gives the first OpenMP target + * region in the "main" function. + * The ".kd" suffix is added by the LLVM assembler when it creates the + * kernel meta-data, and this is what we need to launch a kernel. */ + asm ("s_getpc_b64 %0\n\t" + "s_add_u32 %L0, %L0, main._omp_fn.0.kd@rel32@lo+4\n\t" + "s_addc_u32 %H0, %H0, main._omp_fn.0.kd@rel32@hi+4" + : "=Sg"(val)); + return val; +} +#pragma omp end declare target + +int +main(int argc, char** argv) +{ + + /* Load the HSA runtime DLL. */ + void *hsalib = dlopen ("libhsa-runtime64.so.1", RTLD_LAZY); + assert (hsalib); + + hsa_status_t (*hsa_signal_create) (hsa_signal_value_t initial_value, + uint32_t num_consumers, + const hsa_agent_t *consumers, + hsa_signal_t *signal) + = dlsym (hsalib, "hsa_signal_create"); + assert (hsa_signal_create); + + uint64_t (*hsa_queue_load_write_index_relaxed) (const hsa_queue_t *queue) + = dlsym (hsalib, "hsa_queue_load_write_index_relaxed"); + assert (hsa_queue_load_write_index_relaxed); + + void (*hsa_signal_store_relaxed) (hsa_signal_t signal, + hsa_signal_value_t value) + = dlsym (hsalib, "hsa_signal_store_relaxed"); + assert (hsa_signal_store_relaxed); + + hsa_signal_value_t (*hsa_signal_wait_relaxed) (hsa_signal_t signal, + hsa_signal_condition_t condition, + hsa_signal_value_t compare_value, + uint64_t timeout_hint, + hsa_wait_state_t wait_state_hint) + = dlsym (hsalib, "hsa_signal_wait_relaxed"); + assert (hsa_signal_wait_relaxed); + + void (*hsa_queue_store_write_index_relaxed) (const hsa_queue_t *queue, + uint64_t value) + = dlsym (hsalib, "hsa_queue_store_write_index_relaxed"); + assert (hsa_queue_store_write_index_relaxed); + + hsa_status_t (*hsa_signal_destroy) (hsa_signal_t signal) + = dlsym (hsalib, "hsa_signal_destroy"); + assert (hsa_signal_destroy); + + /* Set up the device data environment. */ + int test_data_value = 0; +#pragma omp target enter data map(test_data_value) + + /* Get the interop details. */ + int device_num = omp_get_default_device(); + hsa_agent_t *gpu_agent; + hsa_queue_t *hsa_queue = NULL; + + omp_interop_t interop = omp_interop_none; +#pragma omp interop init(target, targetsync, prefer_type("hsa"): interop) device(device_num) + assert (interop != omp_interop_none); + + omp_interop_rc_t retcode; + omp_interop_fr_t fr = omp_get_interop_int (interop, omp_ipr_fr_id, &retcode); + assert (retcode == omp_irc_success); + assert (fr == omp_ifr_hsa); + + gpu_agent = omp_get_interop_ptr(interop, omp_ipr_device, &retcode); + assert (retcode == omp_irc_success); + + hsa_queue = omp_get_interop_ptr(interop, omp_ipr_targetsync, &retcode); + assert (retcode == omp_irc_success); + assert (hsa_queue); + + /* Call an offload kernel via OpenMP/libgomp. + * + * This kernel serves two purposes: + * 1) Lookup the device-side load-address of itself (thus avoiding the + * need to access the libgomp internals). + * 2) Count how many times it is called. + * We then call it once using OpenMP, and once manually, and check + * the counter reads "2". */ + uint64_t kernel_object = 0; +#pragma omp target map(from:kernel_object) map(present,alloc:test_data_value) + { + kernel_object = get_kernel_ptr (); + ++test_data_value; + } + + assert (kernel_object != 0); + + /* Configure the same kernel to run again, using HSA manually this time. */ + hsa_status_t status; + hsa_signal_t signal; + status = hsa_signal_create(1, 0, NULL, &signal); + assert (status == HSA_STATUS_SUCCESS); + + /* The kernel is built by GCC for OpenMP, so we need to pass the same + * data pointers that libgomp would pass in. */ + struct { + uintptr_t test_data_value; + uintptr_t kernel_object; + } tgtaddrs; + +#pragma omp target data use_device_addr(test_data_value) + { + tgtaddrs.test_data_value = (uintptr_t)&test_data_value; + tgtaddrs.kernel_object = (uintptr_t)omp_target_alloc (8, device_num); + } + + /* We also need to duplicate the launch ABI used by plugin-gcn.c. */ + struct kernargs_abi args; /* From libgomp-gcn.h. */ + args.dummy1 = (int64_t)&tgtaddrs; + args.out_ptr = (int64_t)malloc (sizeof (struct output)); /* Host side. */ + args.heap_ptr = (int64_t)omp_target_alloc (HEAPSIZE, device_num); + args.arena_ptr = (int64_t)omp_target_alloc (ARENASIZE, device_num); + args.stack_ptr = (int64_t)omp_target_alloc (STACKSIZE, device_num); + args.arena_size_per_team = ARENASIZE; + args.stack_size_per_thread = STACKSIZE; + + /* Build the HSA dispatch packet, and insert it into the queue. */ + uint64_t packet_id = hsa_queue_load_write_index_relaxed (hsa_queue); + const uint32_t queueMask = hsa_queue->size - 1; + hsa_kernel_dispatch_packet_t *dispatch_packet = + &(((hsa_kernel_dispatch_packet_t *) + (hsa_queue->base_address))[packet_id & queueMask]); + + dispatch_packet->setup = 3 << HSA_KERNEL_DISPATCH_PACKET_SETUP_DIMENSIONS; + dispatch_packet->workgroup_size_x = 1; + dispatch_packet->workgroup_size_y = 64; + dispatch_packet->workgroup_size_z = 1; + dispatch_packet->grid_size_x = 1; + dispatch_packet->grid_size_y = 64; + dispatch_packet->grid_size_z = 1; + dispatch_packet->completion_signal = signal; + dispatch_packet->kernel_object = kernel_object; + dispatch_packet->kernarg_address = &args; + dispatch_packet->private_segment_size = 0; + dispatch_packet->group_segment_size = 1536; + + uint16_t header = 0; + header |= HSA_PACKET_TYPE_KERNEL_DISPATCH << HSA_PACKET_HEADER_TYPE; + header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_ACQUIRE_FENCE_SCOPE; + header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_RELEASE_FENCE_SCOPE; + + /* Finish writing the packet header with an atomic release. */ + __atomic_store_n((uint16_t*)dispatch_packet, header, __ATOMIC_RELEASE); + + hsa_queue_store_write_index_relaxed (hsa_queue, packet_id + 1); + + ;/* Run the kernel and wait for it to complete. */ + hsa_signal_store_relaxed(hsa_queue->doorbell_signal, packet_id); + while (hsa_signal_wait_relaxed(signal, HSA_SIGNAL_CONDITION_LT, 1, + UINT64_MAX, HSA_WAIT_STATE_ACTIVE) != 0) + ; + + /* Clean up HSA. */ + hsa_signal_destroy(signal); + free ((void*)args.out_ptr); + omp_target_free ((void*)args.heap_ptr, device_num); + omp_target_free ((void*)args.arena_ptr, device_num); + omp_target_free ((void*)args.stack_ptr, device_num); + omp_target_free ((void*)tgtaddrs.kernel_object, device_num); + + /* Clean up OpenMP. */ + #pragma omp interop destroy(interop) + + /* Bring the data back from the device. */ +#pragma omp target exit data map(test_data_value) + + /* Ensure the kernel was called twice. Once by OpenMP, once by HSA. */ + assert (test_data_value == 2); + + return 0; +} diff --git a/libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-1.C b/libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-1.C index f2ef751..08c5766 100644 --- a/libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-1.C +++ b/libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-1.C @@ -4,9 +4,6 @@ { dg-additional-options -fexceptions } */ /* { dg-additional-options -fdump-tree-optimized-raw } { dg-additional-options -foffload-options=-fdump-tree-optimized-raw } */ -/* { dg-bogus {Size expression must be absolute\.} PR119737 { target { openacc_radeon_accel_selected && __OPTIMIZE__ } xfail *-*-* } 0 } - { dg-ice PR119737 { openacc_radeon_accel_selected && __OPTIMIZE__ } } - { dg-excess-errors {'mkoffload' failure etc.} { xfail { openacc_radeon_accel_selected && __OPTIMIZE__ } } } */ /* See also '../libgomp.c++/target-exceptions-throw-1.C'. */ diff --git a/libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-2.C b/libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-2.C index f6dc970..a7408cd 100644 --- a/libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-2.C +++ b/libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-2.C @@ -6,9 +6,6 @@ { dg-additional-options -foffload-options=-fdump-tree-optimized-raw } */ /* { dg-bogus {undefined symbol: typeinfo name for MyException} PR119806 { target { openacc_radeon_accel_selected && { ! __OPTIMIZE__ } } xfail *-*-* } 0 } { dg-excess-errors {'mkoffload' failure etc.} { xfail { openacc_radeon_accel_selected && { ! __OPTIMIZE__ } } } } */ -/* { dg-bogus {Size expression must be absolute\.} PR119737 { target { openacc_radeon_accel_selected && __OPTIMIZE__ } xfail *-*-* } 0 } - { dg-ice PR119737 { openacc_radeon_accel_selected && __OPTIMIZE__ } } - { dg-excess-errors {'mkoffload' failures etc.} { xfail { openacc_radeon_accel_selected && __OPTIMIZE__ } } } */ /* { dg-bogus {Initial value type mismatch} PR119806 { target { openacc_nvidia_accel_selected && { ! __OPTIMIZE__ } } xfail *-*-* } 0 } { dg-excess-errors {'mkoffload' failure etc.} { xfail { openacc_nvidia_accel_selected && { ! __OPTIMIZE__ } } } } */ diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4615d0f..6433d3f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,36 @@ +2025-04-24 Jonathan Wakely <jwakely@redhat.com> + + * testsuite/23_containers/forward_list/48101_neg.cc: Remove + dg-prune-output that doesn't match anything. + * testsuite/23_containers/list/48101_neg.cc: Likewise. + * testsuite/23_containers/multiset/48101_neg.cc: Likewise. + * testsuite/23_containers/set/48101_neg.cc: Likewise. + +2025-04-24 Jonathan Wakely <jwakely@redhat.com> + + * include/std/generator (generator::yield_value): Add overload + taking lvalue element_of view, as per LWG 3899. + * testsuite/24_iterators/range_generators/lwg3899.cc: New test. + +2025-04-24 François Dumont <frs.dumont@gmail.com> + + * testsuite/util/replacement_memory_operators.h: Adapt for -fno-exceptions + context. + * testsuite/23_containers/deque/capacity/shrink_to_fit.cc: Adapt test + to check std::deque shrink_to_fit method. + +2025-04-23 Andreas Schwab <schwab@linux-m68k.org> + + * config/abi/post/powerpc-linux-gnu/baseline_symbols.txt: Update. + * config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt: Update. + * config/abi/post/powerpc64-linux-gnu/baseline_symbols.txt: Update. + +2025-04-23 ZENG Hao <c@cyano.cn> + + * src/c++23/std.cc.in (atomic_signed_lock_free): Guard with + preprocessor check for __cpp_lib_atomic_lock_free_type_aliases. + (atomic_unsigned_lock_free): Likewise. + 2025-04-22 Patrick Palka <ppalka@redhat.com> Revert: diff --git a/libstdc++-v3/include/bits/formatfwd.h b/libstdc++-v3/include/bits/formatfwd.h index a6b5ac8..3fa01ad 100644 --- a/libstdc++-v3/include/bits/formatfwd.h +++ b/libstdc++-v3/include/bits/formatfwd.h @@ -37,6 +37,12 @@ // <bits/version.h> must have been included before this header: #ifdef __glibcxx_format // C++ >= 20 && HOSTED +#include <concepts> +#include <type_traits> +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED +# include <bits/ranges_base.h> // input_range, range_reference_t +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -50,6 +56,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [format.formatter], formatter template<typename _Tp, typename _CharT = char> struct formatter; +/// @cond undocumented + [[noreturn]] + inline void + __throw_format_error(const char* __what); + namespace __format { #ifdef _GLIBCXX_USE_WCHAR_T @@ -60,9 +71,97 @@ namespace __format concept __char = same_as<_CharT, char>; #endif - template<__char _CharT> - struct __formatter_int; + enum _Align { + _Align_default, + _Align_left, + _Align_right, + _Align_centre, + }; + + template<typename _CharT> struct _Spec; + + template<__char _CharT> struct __formatter_str; + template<__char _CharT> struct __formatter_int; + template<__char _CharT> struct __formatter_ptr; + + template<typename _Tp, typename _Context, + typename _Formatter + = typename _Context::template formatter_type<remove_const_t<_Tp>>, + typename _ParseContext + = basic_format_parse_context<typename _Context::char_type>> + concept __parsable_with + = semiregular<_Formatter> + && requires (_Formatter __f, _ParseContext __pc) + { + { __f.parse(__pc) } -> same_as<typename _ParseContext::iterator>; + }; + + template<typename _Tp, typename _Context, + typename _Formatter + = typename _Context::template formatter_type<remove_const_t<_Tp>>, + typename _ParseContext + = basic_format_parse_context<typename _Context::char_type>> + concept __formattable_with + = semiregular<_Formatter> + && requires (const _Formatter __cf, _Tp&& __t, _Context __fc) + { + { __cf.format(__t, __fc) } -> same_as<typename _Context::iterator>; + }; + + // An unspecified output iterator type used in the `formattable` concept. + template<typename _CharT> + struct _Iter_for; + template<typename _CharT> + using _Iter_for_t = typename _Iter_for<_CharT>::type; + + template<typename _Tp, typename _CharT, + typename _Context = basic_format_context<_Iter_for_t<_CharT>, _CharT>> + concept __formattable_impl + = __parsable_with<_Tp, _Context> && __formattable_with<_Tp, _Context>; + + template<typename _Formatter> + concept __has_debug_format = requires(_Formatter __f) + { + __f.set_debug_format(); + }; +} // namespace __format +/// @endcond + +#if __glibcxx_format_ranges // C++ >= 23 && HOSTED + // [format.formattable], concept formattable + template<typename _Tp, typename _CharT> + concept formattable + = __format::__formattable_impl<remove_reference_t<_Tp>, _CharT>; + + template<typename _Tp, __format::__char _CharT = char> + requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT> + class range_formatter; + +/// @cond undocumented +namespace __format +{ + template<typename _Rg, typename _CharT> + concept __const_formattable_range + = ranges::input_range<const _Rg> + && formattable<ranges::range_reference_t<const _Rg>, _CharT>; + + // _Rg& and const _Rg& are both formattable and use same formatter + // specialization for their references. + template<typename _Rg, typename _CharT> + concept __simply_formattable_range + = __const_formattable_range<_Rg, _CharT> + && same_as<remove_cvref_t<ranges::range_reference_t<_Rg>>, + remove_cvref_t<ranges::range_reference_t<const _Rg>>>; + + template<typename _Rg, typename _CharT> + using __maybe_const_range + = __conditional_t<__const_formattable_range<_Rg, _CharT>, const _Rg, _Rg>; + + template<typename _Tp, typename _CharT> + using __maybe_const + = __conditional_t<formattable<const _Tp, _CharT>, const _Tp, _Tp>; } +#endif // format_ranges _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h index 554e076..a3a8bc1 100644 --- a/libstdc++-v3/include/bits/stl_queue.h +++ b/libstdc++-v3/include/bits/stl_queue.h @@ -70,6 +70,10 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if __glibcxx_format_ranges + template<typename, typename> class formatter; +#endif + /** * @brief A standard container giving FIFO behavior. * @@ -369,6 +373,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION swap(c, __q.c); } #endif // __cplusplus >= 201103L + +#if __glibcxx_format_ranges + friend class formatter<queue<_Tp, _Sequence>, char>; + friend class formatter<queue<_Tp, _Sequence>, wchar_t>; +#endif }; #if __cpp_deduction_guides >= 201606 @@ -898,6 +907,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION swap(comp, __pq.comp); } #endif // __cplusplus >= 201103L + +#if __glibcxx_format_ranges + friend class formatter<priority_queue<_Tp, _Sequence, _Compare>, char>; + friend class formatter<priority_queue<_Tp, _Sequence, _Compare>, wchar_t>; +#endif }; #if __cpp_deduction_guides >= 201606 diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h index 7b32464..27c79d6 100644 --- a/libstdc++-v3/include/bits/stl_stack.h +++ b/libstdc++-v3/include/bits/stl_stack.h @@ -70,6 +70,10 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if __glibcxx_format_ranges + template<typename, typename> class formatter; +#endif + /** * @brief A standard container giving FILO behavior. * @@ -343,6 +347,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION swap(c, __s.c); } #endif // __cplusplus >= 201103L + +#if __glibcxx_format_ranges + friend class formatter<stack<_Tp, _Sequence>, char>; + friend class formatter<stack<_Tp, _Sequence>, wchar_t>; +#endif }; #if __cpp_deduction_guides >= 201606 diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 6b35f99..6caf937 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1390,27 +1390,25 @@ namespace __rb_tree _M_end() const _GLIBCXX_NOEXCEPT { return this->_M_impl._M_header._M_base_ptr(); } - static const _Key& - _S_key(const _Node& __node) - { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2542. Missing const requirements for associative containers + template<typename _Key1, typename _Key2> + bool + _M_key_compare(const _Key1& __k1, const _Key2& __k2) const + { #if __cplusplus >= 201103L - // If we're asking for the key we're presumably using the comparison - // object, and so this is a good place to sanity check it. - static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{}, - "comparison object must be invocable " - "with two arguments of key type"); -# if __cplusplus >= 201703L - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 2542. Missing const requirements for associative containers - if constexpr (__is_invocable<_Compare&, const _Key&, const _Key&>{}) + // Enforce this here with a user-friendly message. static_assert( - is_invocable_v<const _Compare&, const _Key&, const _Key&>, - "comparison object must be invocable as const"); -# endif // C++17 -#endif // C++11 + __is_invocable<const _Compare&, const _Key&, const _Key&>::value, + "comparison object must be invocable with two arguments of key type" + ); +#endif + return _M_impl._M_key_compare(__k1, __k2); + } - return _KeyOfValue()(*__node._M_valptr()); - } + static const _Key& + _S_key(const _Node& __node) + { return _KeyOfValue()(*__node._M_valptr()); } static const _Key& _S_key(_Base_ptr __x) @@ -1933,7 +1931,7 @@ namespace __rb_tree _M_find_tr(const _Kt& __k) const { const_iterator __j(_M_lower_bound_tr(__k)); - if (__j != end() && _M_impl._M_key_compare(__k, _S_key(__j._M_node))) + if (__j != end() && _M_key_compare(__k, _S_key(__j._M_node))) __j = end(); return __j; } @@ -1955,7 +1953,7 @@ namespace __rb_tree auto __x = _M_begin(); auto __y = _M_end(); while (__x) - if (!_M_impl._M_key_compare(_S_key(__x), __k)) + if (!_M_key_compare(_S_key(__x), __k)) { __y = __x; __x = _S_left(__x); @@ -1973,7 +1971,7 @@ namespace __rb_tree auto __x = _M_begin(); auto __y = _M_end(); while (__x) - if (_M_impl._M_key_compare(__k, _S_key(__x))) + if (_M_key_compare(__k, _S_key(__x))) { __y = __x; __x = _S_left(__x); @@ -2474,8 +2472,8 @@ namespace __rb_tree _NodeGen& __node_gen) { bool __insert_left = (__x || __p == _M_end() - || _M_impl._M_key_compare(_KeyOfValue()(__v), - _S_key(__p))); + || _M_key_compare(_KeyOfValue()(__v), + _S_key(__p))); _Base_ptr __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v))->_M_base_ptr(); @@ -2500,8 +2498,8 @@ namespace __rb_tree #endif { bool __insert_left = (__p == _M_end() - || !_M_impl._M_key_compare(_S_key(__p), - _KeyOfValue()(__v))); + || !_M_key_compare(_S_key(__p), + _KeyOfValue()(__v))); _Base_ptr __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v))->_M_base_ptr(); @@ -2529,7 +2527,7 @@ namespace __rb_tree while (__x) { __y = __x; - __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? + __x = !_M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? _S_left(__x) : _S_right(__x); } return _M_insert_lower(__y, _GLIBCXX_FORWARD(_Arg, __v)); @@ -2601,7 +2599,7 @@ namespace __rb_tree const _Key& __k) const { while (__x) - if (!_M_impl._M_key_compare(_S_key(__x), __k)) + if (!_M_key_compare(_S_key(__x), __k)) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); @@ -2617,7 +2615,7 @@ namespace __rb_tree const _Key& __k) const { while (__x) - if (_M_impl._M_key_compare(__k, _S_key(__x))) + if (_M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else __x = _S_right(__x); @@ -2639,9 +2637,9 @@ namespace __rb_tree _Base_ptr __y = _M_end(); while (__x) { - if (_M_impl._M_key_compare(_S_key(__x), __k)) + if (_M_key_compare(_S_key(__x), __k)) __x = _S_right(__x); - else if (_M_impl._M_key_compare(__k, _S_key(__x))) + else if (_M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else { @@ -2671,9 +2669,9 @@ namespace __rb_tree _Base_ptr __y = _M_end(); while (__x) { - if (_M_impl._M_key_compare(_S_key(__x), __k)) + if (_M_key_compare(_S_key(__x), __k)) __x = _S_right(__x); - else if (_M_impl._M_key_compare(__k, _S_key(__x))) + else if (_M_key_compare(__k, _S_key(__x))) __y = __x, __x = _S_left(__x); else { @@ -2737,7 +2735,7 @@ namespace __rb_tree while (__x) { __y = __x; - __comp = _M_impl._M_key_compare(__k, _S_key(__x)); + __comp = _M_key_compare(__k, _S_key(__x)); __x = __comp ? _S_left(__x) : _S_right(__x); } iterator __j = iterator(__y); @@ -2748,7 +2746,7 @@ namespace __rb_tree else --__j; } - if (_M_impl._M_key_compare(_S_key(__j._M_node), __k)) + if (_M_key_compare(_S_key(__j._M_node), __k)) return _Res(__x, __y); return _Res(__j._M_node, _Base_ptr()); } @@ -2768,8 +2766,7 @@ namespace __rb_tree while (__x) { __y = __x; - __x = _M_impl._M_key_compare(__k, _S_key(__x)) ? - _S_left(__x) : _S_right(__x); + __x = _M_key_compare(__k, _S_key(__x)) ? _S_left(__x) : _S_right(__x); } return _Res(__x, __y); } @@ -2838,19 +2835,18 @@ namespace __rb_tree // end() if (__position._M_node == _M_end()) { - if (size() > 0 - && _M_impl._M_key_compare(_S_key(_M_rightmost()), __k)) + if (size() > 0 && _M_key_compare(_S_key(_M_rightmost()), __k)) return _Res(_Base_ptr(), _M_rightmost()); else return _M_get_insert_unique_pos(__k); } - else if (_M_impl._M_key_compare(__k, _S_key(__position._M_node))) + else if (_M_key_compare(__k, _S_key(__position._M_node))) { // First, try before... iterator __before(__position._M_node); if (__position._M_node == _M_leftmost()) // begin() return _Res(_M_leftmost(), _M_leftmost()); - else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), __k)) + else if (_M_key_compare(_S_key((--__before)._M_node), __k)) { if (!_S_right(__before._M_node)) return _Res(_Base_ptr(), __before._M_node); @@ -2860,13 +2856,13 @@ namespace __rb_tree else return _M_get_insert_unique_pos(__k); } - else if (_M_impl._M_key_compare(_S_key(__position._M_node), __k)) + else if (_M_key_compare(_S_key(__position._M_node), __k)) { // ... then try after. iterator __after(__position._M_node); if (__position._M_node == _M_rightmost()) return _Res(_Base_ptr(), _M_rightmost()); - else if (_M_impl._M_key_compare(__k, _S_key((++__after)._M_node))) + else if (_M_key_compare(__k, _S_key((++__after)._M_node))) { if (!_S_right(__position._M_node)) return _Res(_Base_ptr(), __position._M_node); @@ -2923,18 +2919,18 @@ namespace __rb_tree if (__position._M_node == _M_end()) { if (size() > 0 - && !_M_impl._M_key_compare(__k, _S_key(_M_rightmost()))) + && !_M_key_compare(__k, _S_key(_M_rightmost()))) return _Res(_Base_ptr(), _M_rightmost()); else return _M_get_insert_equal_pos(__k); } - else if (!_M_impl._M_key_compare(_S_key(__position._M_node), __k)) + else if (!_M_key_compare(_S_key(__position._M_node), __k)) { // First, try before... iterator __before(__position._M_node); if (__position._M_node == _M_leftmost()) // begin() return _Res(_M_leftmost(), _M_leftmost()); - else if (!_M_impl._M_key_compare(__k, _S_key((--__before)._M_node))) + else if (!_M_key_compare(__k, _S_key((--__before)._M_node))) { if (!_S_right(__before._M_node)) return _Res(_Base_ptr(), __before._M_node); @@ -2950,7 +2946,7 @@ namespace __rb_tree iterator __after(__position._M_node); if (__position._M_node == _M_rightmost()) return _Res(_Base_ptr(), _M_rightmost()); - else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), __k)) + else if (!_M_key_compare(_S_key((++__after)._M_node), __k)) { if (!_S_right(__position._M_node)) return _Res(_Base_ptr(), __position._M_node); @@ -2999,8 +2995,7 @@ namespace __rb_tree -> iterator { bool __insert_left = (__x || __p == _M_end() - || _M_impl._M_key_compare(_S_key(__z), - _S_key(__p))); + || _M_key_compare(_S_key(__z), _S_key(__p))); _Base_ptr __base_z = __z->_M_base_ptr(); _Node_traits::_S_insert_and_rebalance @@ -3017,8 +3012,7 @@ namespace __rb_tree -> iterator { bool __insert_left = (__p == _M_end() - || !_M_impl._M_key_compare(_S_key(__p), - _S_key(__z))); + || !_M_key_compare(_S_key(__p), _S_key(__z))); _Base_ptr __base_z = __z->_M_base_ptr(); _Node_traits::_S_insert_and_rebalance @@ -3039,7 +3033,7 @@ namespace __rb_tree while (__x) { __y = __x; - __x = !_M_impl._M_key_compare(_S_key(__x), _S_key(__z)) ? + __x = !_M_key_compare(_S_key(__x), _S_key(__z)) ? _S_left(__x) : _S_right(__x); } return _M_insert_lower_node(__y, __z); @@ -3151,8 +3145,7 @@ namespace __rb_tree { iterator __j(_M_lower_bound(_M_begin(), _M_end(), __k)); return (__j == end() - || _M_impl._M_key_compare(__k, - _S_key(__j._M_node))) ? end() : __j; + || _M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } template<typename _Key, typename _Val, typename _KeyOfValue, @@ -3164,8 +3157,7 @@ namespace __rb_tree { const_iterator __j(_M_lower_bound(_M_begin(), _M_end(), __k)); return (__j == end() - || _M_impl._M_key_compare(__k, - _S_key(__j._M_node))) ? end() : __j; + || _M_key_compare(__k, _S_key(__j._M_node))) ? end() : __j; } template<typename _Key, typename _Val, typename _KeyOfValue, @@ -3205,9 +3197,9 @@ namespace __rb_tree || (__R && __R->_M_color == _S_red)) return false; - if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) + if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) return false; - if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) + if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) return false; if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 0afaf0d..737b3f4 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -1416,9 +1416,8 @@ ftms = { // 202207 P2286R8 Formatting Ranges // 202207 P2585R1 Improving default container formatting // LWG3750 Too many papers bump __cpp_lib_format - no_stdname = true; // TODO remove values = { - v = 1; // TODO 202207 + v = 202207; cxxmin = 23; hosted = yes; }; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 980fee6..59ff0ce 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -1562,8 +1562,9 @@ #if !defined(__cpp_lib_format_ranges) # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED -# define __glibcxx_format_ranges 1L +# define __glibcxx_format_ranges 202207L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_format_ranges) +# define __cpp_lib_format_ranges 202207L # endif # endif #endif /* !defined(__cpp_lib_format_ranges) && defined(__glibcxx_want_format_ranges) */ diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format index e557e10..69d8d18 100644 --- a/libstdc++-v3/include/std/format +++ b/libstdc++-v3/include/std/format @@ -56,7 +56,7 @@ #include <bits/ranges_base.h> // input_range, range_reference_t #include <bits/ranges_util.h> // subrange #include <bits/ranges_algobase.h> // ranges::copy -#include <bits/stl_iterator.h> // back_insert_iterator +#include <bits/stl_iterator.h> // back_insert_iterator, counted_iterator #include <bits/stl_pair.h> // __is_pair #include <bits/unicode.h> // __is_scalar_value, _Utf_view, etc. #include <bits/utility.h> // tuple_size_v @@ -99,24 +99,22 @@ namespace __format // Size for stack located buffer template<typename _CharT> - constexpr size_t __stackbuf_size = 32 * sizeof(void*) / sizeof(_CharT); + constexpr size_t __stackbuf_size = 32 * sizeof(void*) / sizeof(_CharT); // Type-erased character sinks. template<typename _CharT> class _Sink; template<typename _CharT> class _Fixedbuf_sink; - template<typename _Seq> class _Seq_sink; - - template<typename _CharT, typename _Alloc = allocator<_CharT>> - using _Str_sink - = _Seq_sink<basic_string<_CharT, char_traits<_CharT>, _Alloc>>; - - // template<typename _CharT, typename _Alloc = allocator<_CharT>> - // using _Vec_sink = _Seq_sink<vector<_CharT, _Alloc>>; + template<typename _Out, typename _CharT> class _Padding_sink; // Output iterator that writes to a type-erase character sink. template<typename _CharT> class _Sink_iter; + // An unspecified output iterator type used in the `formattable` concept. + template<typename _CharT> + struct _Iter_for + { using type = back_insert_iterator<basic_string<_CharT>>; }; + template<typename _CharT> using __format_context = basic_format_context<_Sink_iter<_CharT>, _CharT>; @@ -135,6 +133,7 @@ namespace __format template<typename, typename...> friend struct std::basic_format_string; }; + } // namespace __format /// @endcond @@ -485,13 +484,6 @@ namespace __format _Pres_esc = 0xf, // For strings, charT and ranges }; - enum _Align { - _Align_default, - _Align_left, - _Align_right, - _Align_centre, - }; - enum _Sign { _Sign_default, _Sign_plus, @@ -886,6 +878,25 @@ namespace __format __spec._M_fill); } + template<typename _CharT> + size_t + __truncate(basic_string_view<_CharT>& __s, size_t __prec) + { + if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) + { + if (__prec != (size_t)-1) + return __unicode::__truncate(__s, __prec); + else + return __unicode::__field_width(__s); + } + else + { + __s = __s.substr(0, __prec); + return __s.size(); + } + } + + // Values are indices into _Escapes::all. enum class _Term_char : unsigned char { _Tc_quote = 12, @@ -1321,82 +1332,111 @@ namespace __format format(basic_string_view<_CharT> __s, basic_format_context<_Out, _CharT>& __fc) const { - constexpr auto __term = __format::_Term_char::_Tc_quote; - const auto __write_direct = [&] - { - if (_M_spec._M_type == _Pres_esc) - return __format::__write_escaped(__fc.out(), __s, __term); - else - return __format::__write(__fc.out(), __s); - }; + if (_M_spec._M_type == _Pres_esc) + return _M_format_escaped(__s, __fc); if (_M_spec._M_width_kind == _WP_none && _M_spec._M_prec_kind == _WP_none) - return __write_direct(); + return __format::__write(__fc.out(), __s); - const size_t __prec = - _M_spec._M_prec_kind != _WP_none - ? _M_spec._M_get_precision(__fc) - : basic_string_view<_CharT>::npos; + const size_t __maxwidth = _M_spec._M_get_precision(__fc); + const size_t __width = __format::__truncate(__s, __maxwidth); + return __format::__write_padded_as_spec(__s, __width, __fc, _M_spec); + } - const size_t __estimated_width = _S_trunc(__s, __prec); - // N.B. Escaping only increases width - if (_M_spec._M_get_width(__fc) <= __estimated_width - && _M_spec._M_prec_kind == _WP_none) - return __write_direct(); + template<typename _Out> + _Out + _M_format_escaped(basic_string_view<_CharT> __s, + basic_format_context<_Out, _CharT>& __fc) const + { + constexpr auto __term = __format::_Term_char::_Tc_quote; + const size_t __padwidth = _M_spec._M_get_width(__fc); + if (__padwidth == 0 && _M_spec._M_prec_kind == _WP_none) + return __format::__write_escaped(__fc.out(), __s, __term); - if (_M_spec._M_type != _Pres_esc) - return __format::__write_padded_as_spec(__s, __estimated_width, - __fc, _M_spec); + const size_t __maxwidth = _M_spec._M_get_precision(__fc); + const size_t __width = __truncate(__s, __maxwidth); + // N.B. Escaping only increases width + if (__padwidth <= __width && _M_spec._M_prec_kind == _WP_none) + return __format::__write_escaped(__fc.out(), __s, __term); - __format::_Str_sink<_CharT> __sink; - __format::__write_escaped(__sink.out(), __s, __term); - basic_string_view<_CharT> __escaped(__sink.view().data(), - __sink.view().size()); - const size_t __escaped_width = _S_trunc(__escaped, __prec); // N.B. [tab:format.type.string] defines '?' as // Copies the escaped string ([format.string.escaped]) to the output, // so precision seem to appy to escaped string. - return __format::__write_padded_as_spec(__escaped, __escaped_width, - __fc, _M_spec); + _Padding_sink<_Out, _CharT> __sink(__fc.out(), __padwidth, __maxwidth); + __format::__write_escaped(__sink.out(), __s, __term); + return __sink._M_finish(_M_spec._M_align, _M_spec._M_fill); } #if __glibcxx_format_ranges // C++ >= 23 && HOSTED template<ranges::input_range _Rg, typename _Out> requires same_as<remove_cvref_t<ranges::range_reference_t<_Rg>>, _CharT> - typename basic_format_context<_Out, _CharT>::iterator + _Out _M_format_range(_Rg&& __rg, basic_format_context<_Out, _CharT>& __fc) const { + using _Range = remove_reference_t<_Rg>; using _String = basic_string<_CharT>; using _String_view = basic_string_view<_CharT>; - if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) + if constexpr (!is_lvalue_reference_v<_Rg>) + return _M_format_range<_Range&>(__rg, __fc); + else if constexpr (!is_const_v<_Range> + && __simply_formattable_range<_Range, _CharT>) + return _M_format_range<const _Range&>(__rg, __fc); + else if constexpr (ranges::contiguous_range<_Rg>) + { + _String_view __str(ranges::data(__rg), + size_t(ranges::distance(__rg))); + return format(__str, __fc); + } + else if (_M_spec._M_type != _Pres_esc) + { + const size_t __padwidth = _M_spec._M_get_width(__fc); + if (__padwidth == 0 && _M_spec._M_prec_kind == _WP_none) + return ranges::copy(__rg, __fc.out()).out; + + _Padding_sink<_Out, _CharT> __sink(__fc.out(), __padwidth, + _M_spec._M_get_precision(__fc)); + ranges::copy(__rg, __sink.out()); + return __sink._M_finish(_M_spec._M_align, _M_spec._M_fill); + } + else if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>) { const size_t __n(ranges::distance(__rg)); - if constexpr (ranges::contiguous_range<_Rg>) - return format(_String_view(ranges::data(__rg), __n), __fc); - else if (__n <= __format::__stackbuf_size<_CharT>) + size_t __w = __n; + if constexpr (!__unicode::__literal_encoding_is_unicode<_CharT>()) + if (size_t __max = _M_spec._M_get_precision(__fc); __n > __max) + __w == __max; + + if (__w <= __format::__stackbuf_size<_CharT>) { _CharT __buf[__format::__stackbuf_size<_CharT>]; - ranges::copy(__rg, __buf); - return format(_String_view(__buf, __n), __fc); + ranges::copy_n(ranges::begin(__rg), __w, __buf); + return _M_format_escaped(_String_view(__buf, __n), __fc); } - else if constexpr (ranges::sized_range<_Rg>) - return format(_String(from_range, __rg), __fc); else if constexpr (ranges::random_access_range<_Rg>) { ranges::iterator_t<_Rg> __first = ranges::begin(__rg); - ranges::subrange __sub(__first, __first + __n); - return format(_String(from_range, __sub), __fc); + ranges::subrange __sub(__first, __first + __w); + return _M_format_escaped(_String(from_range, __sub), __fc); } + else if (__w <= __n) + { + ranges::subrange __sub( + counted_iterator(ranges::begin(__rg), __w), + default_sentinel); + return _M_format_escaped(_String(from_range, __sub), __fc); + } + else if constexpr (ranges::sized_range<_Rg>) + return _M_format_escaped(_String(from_range, __rg), __fc); else { // N.B. preserve the computed size ranges::subrange __sub(__rg, __n); - return format(_String(from_range, __sub), __fc); + return _M_format_escaped(_String(from_range, __sub), __fc); } } else - return format(_String(from_range, __rg), __fc); + return _M_format_escaped(_String(from_range, __rg), __fc); } constexpr void @@ -1405,23 +1445,6 @@ namespace __format #endif private: - static size_t - _S_trunc(basic_string_view<_CharT>& __s, size_t __prec) - { - if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) - { - if (__prec != basic_string_view<_CharT>::npos) - return __unicode::__truncate(__s, __prec); - else - return __unicode::__field_width(__s); - } - else - { - __s = __s.substr(0, __prec); - return __s.size(); - } - } - _Spec<_CharT> _M_spec{}; }; @@ -1434,6 +1457,13 @@ namespace __format static constexpr _Pres_type _AsBool = _Pres_s; static constexpr _Pres_type _AsChar = _Pres_c; + __formatter_int() = default; + + constexpr + __formatter_int(_Spec<_CharT> __spec) noexcept + : _M_spec(__spec) + { } + constexpr typename basic_format_parse_context<_CharT>::iterator _M_do_parse(basic_format_parse_context<_CharT>& __pc, _Pres_type __type) { @@ -2381,6 +2411,134 @@ namespace __format _Spec<_CharT> _M_spec{}; }; + template<__format::__char _CharT> + struct __formatter_ptr + { + __formatter_ptr() = default; + + constexpr + __formatter_ptr(_Spec<_CharT> __spec) noexcept + : _M_spec(__spec) + { } + + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { + __format::_Spec<_CharT> __spec{}; + const auto __last = __pc.end(); + auto __first = __pc.begin(); + + auto __finalize = [this, &__spec] { + _M_spec = __spec; + }; + + auto __finished = [&] { + if (__first == __last || *__first == '}') + { + __finalize(); + return true; + } + return false; + }; + + if (__finished()) + return __first; + + __first = __spec._M_parse_fill_and_align(__first, __last); + if (__finished()) + return __first; + +// _GLIBCXX_RESOLVE_LIB_DEFECTS +// P2510R3 Formatting pointers +#if __glibcxx_format >= 202304L + __first = __spec._M_parse_zero_fill(__first, __last); + if (__finished()) + return __first; +#endif + + __first = __spec._M_parse_width(__first, __last, __pc); + + if (__first != __last) + { + if (*__first == 'p') + ++__first; +#if __glibcxx_format >= 202304L + else if (*__first == 'P') + { + __spec._M_type = __format::_Pres_P; + ++__first; + } +#endif + } + + if (__finished()) + return __first; + + __format::__failed_to_parse_format_spec(); + } + + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(const void* __v, basic_format_context<_Out, _CharT>& __fc) const + { + auto __u = reinterpret_cast<__UINTPTR_TYPE__>(__v); + char __buf[2 + sizeof(__v) * 2]; + auto [__ptr, __ec] = std::to_chars(__buf + 2, std::end(__buf), + __u, 16); + int __n = __ptr - __buf; + __buf[0] = '0'; + __buf[1] = 'x'; +#if __glibcxx_format >= 202304L + if (_M_spec._M_type == __format::_Pres_P) + { + __buf[1] = 'X'; + for (auto __p = __buf + 2; __p != __ptr; ++__p) +#if __has_builtin(__builtin_toupper) + *__p = __builtin_toupper(*__p); +#else + *__p = std::toupper(*__p); +#endif + } +#endif + + basic_string_view<_CharT> __str; + if constexpr (is_same_v<_CharT, char>) + __str = string_view(__buf, __n); +#ifdef _GLIBCXX_USE_WCHAR_T + else + { + auto __p = (_CharT*)__builtin_alloca(__n * sizeof(_CharT)); + std::__to_wstring_numeric(__buf, __n, __p); + __str = wstring_view(__p, __n); + } +#endif + +#if __glibcxx_format >= 202304L + if (_M_spec._M_zero_fill) + { + size_t __width = _M_spec._M_get_width(__fc); + if (__width <= __str.size()) + return __format::__write(__fc.out(), __str); + + auto __out = __fc.out(); + // Write "0x" or "0X" prefix before zero-filling. + __out = __format::__write(std::move(__out), __str.substr(0, 2)); + __str.remove_prefix(2); + size_t __nfill = __width - __n; + return __format::__write_padded(std::move(__out), __str, + __format::_Align_right, + __nfill, _CharT('0')); + } +#endif + + return __format::__write_padded_as_spec(__str, __n, __fc, _M_spec, + __format::_Align_right); + } + + private: + __format::_Spec<_CharT> _M_spec{}; + }; + } // namespace __format /// @endcond @@ -2845,120 +3003,15 @@ namespace __format constexpr typename basic_format_parse_context<_CharT>::iterator parse(basic_format_parse_context<_CharT>& __pc) - { - __format::_Spec<_CharT> __spec{}; - const auto __last = __pc.end(); - auto __first = __pc.begin(); - - auto __finalize = [this, &__spec] { - _M_spec = __spec; - }; - - auto __finished = [&] { - if (__first == __last || *__first == '}') - { - __finalize(); - return true; - } - return false; - }; - - if (__finished()) - return __first; - - __first = __spec._M_parse_fill_and_align(__first, __last); - if (__finished()) - return __first; - -// _GLIBCXX_RESOLVE_LIB_DEFECTS -// P2510R3 Formatting pointers -#if __glibcxx_format >= 202304L - __first = __spec._M_parse_zero_fill(__first, __last); - if (__finished()) - return __first; -#endif - - __first = __spec._M_parse_width(__first, __last, __pc); - - if (__first != __last) - { - if (*__first == 'p') - ++__first; -#if __glibcxx_format >= 202304L - else if (*__first == 'P') - { - __spec._M_type = __format::_Pres_P; - ++__first; - } -#endif - } - - if (__finished()) - return __first; - - __format::__failed_to_parse_format_spec(); - } + { return _M_f.parse(__pc); } template<typename _Out> typename basic_format_context<_Out, _CharT>::iterator format(const void* __v, basic_format_context<_Out, _CharT>& __fc) const - { - auto __u = reinterpret_cast<__UINTPTR_TYPE__>(__v); - char __buf[2 + sizeof(__v) * 2]; - auto [__ptr, __ec] = std::to_chars(__buf + 2, std::end(__buf), - __u, 16); - int __n = __ptr - __buf; - __buf[0] = '0'; - __buf[1] = 'x'; -#if __glibcxx_format >= 202304L - if (_M_spec._M_type == __format::_Pres_P) - { - __buf[1] = 'X'; - for (auto __p = __buf + 2; __p != __ptr; ++__p) -#if __has_builtin(__builtin_toupper) - *__p = __builtin_toupper(*__p); -#else - *__p = std::toupper(*__p); -#endif - } -#endif - - basic_string_view<_CharT> __str; - if constexpr (is_same_v<_CharT, char>) - __str = string_view(__buf, __n); -#ifdef _GLIBCXX_USE_WCHAR_T - else - { - auto __p = (_CharT*)__builtin_alloca(__n * sizeof(_CharT)); - std::__to_wstring_numeric(__buf, __n, __p); - __str = wstring_view(__p, __n); - } -#endif - -#if __glibcxx_format >= 202304L - if (_M_spec._M_zero_fill) - { - size_t __width = _M_spec._M_get_width(__fc); - if (__width <= __str.size()) - return __format::__write(__fc.out(), __str); - - auto __out = __fc.out(); - // Write "0x" or "0X" prefix before zero-filling. - __out = __format::__write(std::move(__out), __str.substr(0, 2)); - __str.remove_prefix(2); - size_t __nfill = __width - __n; - return __format::__write_padded(std::move(__out), __str, - __format::_Align_right, - __nfill, _CharT('0')); - } -#endif - - return __format::__write_padded_as_spec(__str, __n, __fc, _M_spec, - __format::_Align_right); - } + { return _M_f.format(__v, __fc); } private: - __format::_Spec<_CharT> _M_spec{}; + __format::__formatter_ptr<_CharT> _M_f; }; template<__format::__char _CharT> @@ -2977,7 +3030,7 @@ namespace __format { return _M_f.format(__v, __fc); } private: - formatter<const void*, _CharT> _M_f; + __format::__formatter_ptr<_CharT> _M_f; }; template<__format::__char _CharT> @@ -2996,7 +3049,7 @@ namespace __format { return _M_f.format(nullptr, __fc); } private: - formatter<const void*, _CharT> _M_f; + __format::__formatter_ptr<_CharT> _M_f; }; /// @} @@ -3024,59 +3077,6 @@ namespace __format : private formatter<__format::__disabled, wchar_t> { }; #endif -/// @cond undocumented -namespace __format -{ - template<typename _Tp, typename _Context, - typename _Formatter - = typename _Context::template formatter_type<remove_const_t<_Tp>>, - typename _ParseContext - = basic_format_parse_context<typename _Context::char_type>> - concept __parsable_with - = semiregular<_Formatter> - && requires (_Formatter __f, _ParseContext __pc) - { - { __f.parse(__pc) } -> same_as<typename _ParseContext::iterator>; - }; - - template<typename _Tp, typename _Context, - typename _Formatter - = typename _Context::template formatter_type<remove_const_t<_Tp>>, - typename _ParseContext - = basic_format_parse_context<typename _Context::char_type>> - concept __formattable_with - = semiregular<_Formatter> - && requires (const _Formatter __cf, _Tp&& __t, _Context __fc) - { - { __cf.format(__t, __fc) } -> same_as<typename _Context::iterator>; - }; - - // An unspecified output iterator type used in the `formattable` concept. - template<typename _CharT> - using _Iter_for = back_insert_iterator<basic_string<_CharT>>; - - template<typename _Tp, typename _CharT, - typename _Context = basic_format_context<_Iter_for<_CharT>, _CharT>> - concept __formattable_impl - = __parsable_with<_Tp, _Context> && __formattable_with<_Tp, _Context>; - - template<typename _Formatter> - concept __has_debug_format = requires(_Formatter __f) - { - __f.set_debug_format(); - }; - -} // namespace __format -/// @endcond - -#if __glibcxx_format_ranges // C++ >= 23 && HOSTED - // [format.formattable], concept formattable - template<typename _Tp, typename _CharT> - concept formattable - = __format::__formattable_impl<remove_reference_t<_Tp>, _CharT>; - -#endif // format_ranges - /// An iterator after the last character written, and the number of /// characters that would have been written. template<typename _Out> @@ -3318,12 +3318,12 @@ namespace __format // A sink that fills a sequence (e.g. std::string, std::vector, std::deque). // Writes to a buffer then appends that to the sequence when it fills up. template<typename _Seq> - class _Seq_sink final : public _Buf_sink<typename _Seq::value_type> + class _Seq_sink : public _Buf_sink<typename _Seq::value_type> { using _CharT = typename _Seq::value_type; _Seq _M_seq; - + protected: // Transfer buffer contents to the sequence, so buffer can be refilled. void _M_overflow() override @@ -3395,6 +3395,17 @@ namespace __format } } + void _M_trim(span<const _CharT> __s) + requires __is_specialization_of<_Seq, basic_string> + { + _GLIBCXX_DEBUG_ASSERT(__s.data() == this->_M_buf + || __s.data() == _M_seq.data()); + if (__s.data() == _M_seq.data()) + _M_seq.resize(__s.size()); + else + this->_M_reset(this->_M_buf, __s.size()); + } + public: // TODO: for SSO string, use SSO buffer as initial span, then switch // to _M_buf if it overflows? Or even do that for all unused capacity? @@ -3420,7 +3431,7 @@ namespace __format // A writable span that views everything written to the sink. // Will be either a view over _M_seq or the used part of _M_buf. span<_CharT> - view() + _M_span() { auto __s = this->_M_used(); if (_M_seq.size()) @@ -3431,9 +3442,21 @@ namespace __format } return __s; } + + basic_string_view<_CharT> + view() + { + auto __span = _M_span(); + return basic_string_view<_CharT>(__span.data(), __span.size()); + } }; - // A sink that writes to an output iterator. + template<typename _CharT, typename _Alloc = allocator<_CharT>> + using _Str_sink + = _Seq_sink<basic_string<_CharT, char_traits<_CharT>, _Alloc>>; + + // template<typename _CharT, typename _Alloc = allocator<_CharT>> + // using _Vec_sink = _Seq_sink<vector<_CharTthis-> sink that writes to an output iterator. // Writes to a fixed-size buffer and then flushes to the output iterator // when the buffer fills up. template<typename _CharT, typename _OutIter> @@ -3601,6 +3624,173 @@ namespace __format } }; + // A sink for handling the padded outputs (_M_padwidth) or truncated + // (_M_maxwidth). The handling is done by writting to buffer (_Str_strink) + // until sufficient number of characters is written. After that if sequence + // is longer than _M_padwidth it's written to _M_out, and further writes are + // either: + // * buffered and forwarded to _M_out, if below _M_maxwidth, + // * ignored otherwise + // If field width of written sequence is no greater than _M_padwidth, the + // sequence is written during _M_finish call. + template<typename _Out, typename _CharT> + class _Padding_sink : public _Str_sink<_CharT> + { + const size_t _M_padwidth; + const size_t _M_maxwidth; + _Out _M_out; + size_t _M_printwidth; + + [[__gnu__::__always_inline__]] + bool + _M_ignoring() const + { + return _M_printwidth >= _M_maxwidth; + } + + [[__gnu__::__always_inline__]] + bool + _M_buffering() const + { + if (_M_printwidth < _M_padwidth) + return true; + if (_M_maxwidth != (size_t)-1) + return _M_printwidth < _M_maxwidth; + return false; + } + + void + _M_flush() + { + span<_CharT> __new = this->_M_used(); + basic_string_view<_CharT> __str(__new.data(), __new.size()); + _M_out = __format::__write(std::move(_M_out), __str); + this->_M_rewind(); + } + + bool + _M_force_update() + { + auto __str = this->view(); + // Compute actual field width, possibly truncated. + _M_printwidth = __format::__truncate(__str, _M_maxwidth); + if (_M_ignoring()) + this->_M_trim(__str); + if (_M_buffering()) + return true; + + // We have more characters than padidng, no padding is needed, + // write direclty to _M_out. + if (_M_printwidth >= _M_padwidth) + _M_out = __format::__write(std::move(_M_out), __str); + // We reached _M_maxwidth that is smaller than _M_padwidth. + // Store the prefix sequence in _M_seq, and free _M_buf. + else + _Str_sink<_CharT>::_M_overflow(); + + // Use internal buffer for writes to _M_out. + this->_M_reset(this->_M_buf); + return false; + } + + bool + _M_update(size_t __new) + { + _M_printwidth += __new; + if (_M_buffering()) + return true; + return _M_force_update(); + } + + void + _M_overflow() override + { + // Ignore characters in buffer, and override it. + if (_M_ignoring()) + this->_M_rewind(); + // Write buffer to _M_out, and override it. + else if (!_M_buffering()) + _M_flush(); + // Update written count, and if input still should be buffered, + // flush the to _M_seq. + else if (_M_update(this->_M_used().size())) + _Str_sink<_CharT>::_M_overflow(); + } + + typename _Sink<_CharT>::_Reservation + _M_reserve(size_t __n) override + { + // Ignore characters in buffer, if any. + if (_M_ignoring()) + this->_M_rewind(); + else if constexpr (is_same_v<_Out, _Sink_iter<_CharT>>) + if (!_M_buffering()) + { + // Write pending characters if any + if (!this->_M_used().empty()) + _M_flush(); + // Try to reserve from _M_out sink. + if (auto __reserved = _M_out._M_reserve(__n)) + return __reserved; + } + return _Sink<_CharT>::_M_reserve(__n); + } + + void + _M_bump(size_t __n) override + { + // Ignore the written characters. + if (_M_ignoring()) + return; + // If reservation was made directy sink associated _M_out, + // _M_bump will be called on that sink. + _Sink<_CharT>::_M_bump(__n); + if (_M_buffering()) + _M_update(__n); + } + + public: + [[__gnu__::__always_inline__]] + explicit _Padding_sink(_Out __out, size_t __padwidth) + : _M_padwidth(__padwidth), _M_maxwidth(-1), + _M_out(std::move(__out)), _M_printwidth(0) + { } + + [[__gnu__::__always_inline__]] + explicit _Padding_sink(_Out __out, size_t __padwidth, size_t __maxwidth) + : _M_padwidth(__padwidth), _M_maxwidth(__maxwidth), + _M_out(std::move(__out)), _M_printwidth(0) + { } + + _Out + _M_finish(_Align __align, char32_t __fill_char) + { + // Handle any characters in the buffer. + if (auto __rem = this->_M_used().size()) + { + if (_M_ignoring()) + this->_M_rewind(); + else if (!_M_buffering()) + _M_flush(); + else + _M_update(__rem); + } + + if (!_M_buffering() || !_M_force_update()) + // Characters were already written to _M_out. + if (_M_printwidth >= _M_padwidth) + return std::move(_M_out); + + const auto __str = this->view(); + if (_M_printwidth >= _M_padwidth) + return __format::__write(std::move(_M_out), __str); + + const size_t __nfill = _M_padwidth - _M_printwidth; + return __format::__write_padded(std::move(_M_out), __str, + __align, __nfill, __fill_char); + } + }; + enum _Arg_t : unsigned char { _Arg_none, _Arg_bool, _Arg_c, _Arg_i, _Arg_u, _Arg_ll, _Arg_ull, _Arg_flt, _Arg_dbl, _Arg_ldbl, _Arg_str, _Arg_sv, _Arg_ptr, _Arg_handle, @@ -5207,7 +5397,8 @@ namespace __format // as we need to format to temporary buffer, using the same iterator. static_assert(is_same_v<_Out, __format::_Sink_iter<_CharT>>); - if (__spec._M_get_width(__fc) == 0) + const size_t __padwidth = __spec._M_get_width(__fc); + if (__padwidth == 0) return __call(__fc); struct _Restore_out @@ -5216,61 +5407,30 @@ namespace __format : _M_ctx(std::addressof(__fc)), _M_out(__fc.out()) { } - void _M_trigger() + void + _M_disarm() + { _M_ctx = nullptr; } + + ~_Restore_out() { if (_M_ctx) _M_ctx->advance_to(_M_out); - _M_ctx = nullptr; } - ~_Restore_out() - { _M_trigger(); } - private: basic_format_context<_Sink_iter<_CharT>, _CharT>* _M_ctx; _Sink_iter<_CharT> _M_out; }; _Restore_out __restore(__fc); - // TODO Consider double sinking, first buffer of width - // size and then original sink, if first buffer is overun - // we do not need to align - _Str_sink<_CharT> __buf; - __fc.advance_to(__buf.out()); + _Padding_sink<_Sink_iter<_CharT>, _CharT> __sink(__fc.out(), __padwidth); + __fc.advance_to(__sink.out()); __call(__fc); - __restore._M_trigger(); - - basic_string_view<_CharT> __str(__buf.view()); - size_t __width; - if constexpr (__unicode::__literal_encoding_is_unicode<_CharT>()) - __width = __unicode::__field_width(__str); - else - __width = __str.size(); - - return __format::__write_padded_as_spec(__str, __width, __fc, __spec); + __fc.advance_to(__sink._M_finish(__spec._M_align, __spec._M_fill)); + __restore._M_disarm(); + return __fc.out(); } - template<typename _Rg, typename _CharT> - concept __const_formattable_range - = ranges::input_range<const _Rg> - && formattable<ranges::range_reference_t<const _Rg>, _CharT>; - - // _Rg& and const _Rg& are both formattable and use same formatter - // specialization for their references. - template<typename _Rg, typename _CharT> - concept __simply_formattable_range - = __const_formattable_range<_Rg, _CharT> - && same_as<remove_cvref_t<ranges::range_reference_t<_Rg>>, - remove_cvref_t<ranges::range_reference_t<const _Rg>>>; - - template<typename _Rg, typename _CharT> - using __maybe_const_range - = __conditional_t<__const_formattable_range<_Rg, _CharT>, const _Rg, _Rg>; - - template<typename _Tp, typename _CharT> - using __maybe_const - = __conditional_t<formattable<const _Tp, _CharT>, const _Tp, _Tp>; - template<size_t _Pos, typename _Tp, typename _CharT> struct __indexed_formatter_storage { @@ -5493,7 +5653,7 @@ namespace __format }; // [format.range.formatter], class template range_formatter - template<typename _Tp, __format::__char _CharT = char> + template<typename _Tp, __format::__char _CharT> requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT> class range_formatter { diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index b7ab233..0806900 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -1486,12 +1486,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final : __future_base::_Task_state_base<_Res(_Args...)> { +#ifdef __cpp_lib_is_invocable // C++ >= 17 + static_assert(is_invocable_r_v<_Res, _Fn&, _Args...>); +#else + static_assert(__is_invocable<_Fn&, _Args...>::value, + "_Fn& is invocable with _Args..."); +#endif + template<typename _Fn2> _Task_state(_Fn2&& __fn, const _Alloc& __a) : _Task_state_base<_Res(_Args...)>(__a), _M_impl(std::forward<_Fn2>(__fn), __a) { } + template<typename _Fn2> + static shared_ptr<_Task_state_base<_Res(_Args...)>> + _S_create(_Fn2&& __fn, const _Alloc& __a) + { + return std::allocate_shared<_Task_state>(__a, + std::forward<_Fn2>(__fn), + __a); + } + private: virtual void _M_run(_Args&&... __args) @@ -1515,7 +1531,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } virtual shared_ptr<_Task_state_base<_Res(_Args...)>> - _M_reset(); + _M_reset() + { return _S_create(std::move(_M_impl._M_fn), _M_impl); } struct _Impl : _Alloc { @@ -1525,38 +1542,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Fn _M_fn; } _M_impl; }; - - template<typename _Signature, typename _Fn, - typename _Alloc = std::allocator<int>> - shared_ptr<__future_base::_Task_state_base<_Signature>> - __create_task_state(_Fn&& __fn, const _Alloc& __a = _Alloc()) - { - typedef typename decay<_Fn>::type _Fn2; - typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State; - return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a); - } - - template<typename _Fn, typename _Alloc, typename _Res, typename... _Args> - shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>> - __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset() - { - return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn), - static_cast<_Alloc&>(_M_impl)); - } /// @endcond /// packaged_task template<typename _Res, typename... _ArgTypes> class packaged_task<_Res(_ArgTypes...)> { - typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type; + using _State_type = __future_base::_Task_state_base<_Res(_ArgTypes...)>; shared_ptr<_State_type> _M_state; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 3039. Unnecessary decay in thread and packaged_task template<typename _Fn, typename _Fn2 = __remove_cvref_t<_Fn>> - using __not_same - = typename enable_if<!is_same<packaged_task, _Fn2>::value>::type; + using __not_same = __enable_if_t<!is_same<packaged_task, _Fn2>::value>; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4154. The Mandates for std::packaged_task's constructor + // from a callable entity should consider decaying. + template<typename _Fn, typename _Alloc = std::allocator<int>> + using _Task_state + = __future_base::_Task_state<__decay_t<_Fn>, _Alloc, + _Res(_ArgTypes...)>; public: // Construction and destruction @@ -1565,16 +1571,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Fn, typename = __not_same<_Fn>> explicit packaged_task(_Fn&& __fn) - : _M_state( - __create_task_state<_Res(_ArgTypes...)>(std::forward<_Fn>(__fn))) - { -#ifdef __cpp_lib_is_invocable // C++ >= 17 - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 4154. The Mandates for std::packaged_task's constructor - // from a callable entity should consider decaying - static_assert(is_invocable_r_v<_Res, decay_t<_Fn>&, _ArgTypes...>); -#endif - } + : _M_state(_Task_state<_Fn>::_S_create(std::forward<_Fn>(__fn), {})) + { } #if __cplusplus < 201703L // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -1583,8 +1581,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 2921. packaged_task and type-erased allocators template<typename _Fn, typename _Alloc, typename = __not_same<_Fn>> packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn) - : _M_state(__create_task_state<_Res(_ArgTypes...)>( - std::forward<_Fn>(__fn), __a)) + : _M_state(_Task_state<_Fn, _Alloc>::_S_create(std::forward<_Fn>(__fn), + __a)) { } // _GLIBCXX_RESOLVE_LIB_DEFECTS diff --git a/libstdc++-v3/include/std/generator b/libstdc++-v3/include/std/generator index 3f781f1..7ab2c9e 100644 --- a/libstdc++-v3/include/std/generator +++ b/libstdc++-v3/include/std/generator @@ -153,6 +153,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION noexcept { return _Recursive_awaiter { std::move(__r.range) }; } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3899. co_yielding elements of an lvalue generator is + // unnecessarily inefficient + template<typename _R2, typename _V2, typename _A2, typename _U2> + requires std::same_as<_Yield2_t<_R2, _V2>, _Yielded> + auto + yield_value(ranges::elements_of<generator<_R2, _V2, _A2>&, _U2> __r) + noexcept + { return _Recursive_awaiter { std::move(__r.range) }; } + template<ranges::input_range _R, typename _Alloc> requires convertible_to<ranges::range_reference_t<_R>, _Yielded> auto diff --git a/libstdc++-v3/include/std/latch b/libstdc++-v3/include/std/latch index cf64854..dc147c2 100644 --- a/libstdc++-v3/include/std/latch +++ b/libstdc++-v3/include/std/latch @@ -62,7 +62,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr explicit latch(ptrdiff_t __expected) noexcept - : _M_a(__expected) + : _M_counter(__expected) { __glibcxx_assert(__expected >= 0 && __expected <= max()); } ~latch() = default; @@ -74,23 +74,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION count_down(ptrdiff_t __update = 1) { __glibcxx_assert(__update >= 0 && __update <= max()); - auto const __old = __atomic_impl::fetch_sub(&_M_a, __update, + auto const __old = __atomic_impl::fetch_sub(&_M_counter, __update, memory_order::release); if (std::cmp_equal(__old, __update)) - __atomic_impl::notify_all(&_M_a); + __atomic_impl::notify_all(&_M_counter); else __glibcxx_assert(std::cmp_less(__update, __old)); } _GLIBCXX_ALWAYS_INLINE bool try_wait() const noexcept - { return __atomic_impl::load(&_M_a, memory_order::acquire) == 0; } + { return __atomic_impl::load(&_M_counter, memory_order::acquire) == 0; } _GLIBCXX_ALWAYS_INLINE void wait() const noexcept { auto const __pred = [this] { return this->try_wait(); }; - std::__atomic_wait_address(&_M_a, __pred); + std::__atomic_wait_address(&_M_counter, __pred); } _GLIBCXX_ALWAYS_INLINE void @@ -102,7 +102,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: alignas(__detail::__platform_wait_alignment) - __detail::__platform_wait_t _M_a; + __detail::__platform_wait_t _M_counter; }; _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/std/queue b/libstdc++-v3/include/std/queue index 74b6c07..9052589 100644 --- a/libstdc++-v3/include/std/queue +++ b/libstdc++-v3/include/std/queue @@ -61,14 +61,88 @@ #include <bits/requires_hosted.h> // containers +#define __glibcxx_want_adaptor_iterator_pair_constructor +#define __glibcxx_want_containers_ranges +#include <bits/version.h> + #include <deque> #include <vector> #include <bits/stl_heap.h> #include <bits/stl_function.h> #include <bits/stl_queue.h> -#define __glibcxx_want_adaptor_iterator_pair_constructor -#define __glibcxx_want_containers_ranges -#include <bits/version.h> +#ifdef __glibcxx_format_ranges // C++ >= 23 && HOSTED +#include <bits/formatfwd.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + // Standard does not constrain accepted _CharT, we do so we can + // befriend specializations. + template<__format::__char _CharT, typename _Tp, + formattable<_CharT> _Container> + struct formatter<queue<_Tp, _Container>, _CharT> + { + private: + using __maybe_const_adaptor + = __conditional_t< + __format::__const_formattable_range<_Container, _CharT>, + const queue<_Tp, _Container>, queue<_Tp, _Container>>; + + public: + // Standard declares this as template accepting unconstrained + // ParseContext type. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f.parse(__pc); } + + // Standard declares this as template accepting unconstrained + // FormatContext type. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__maybe_const_adaptor& __a, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f.format(__a.c, __fc); } + + private: + // Standard uses formatter<ref_view<_Container>, _CharT>. + range_formatter<_Tp, _CharT> _M_f; + }; + + template<__format::__char _CharT, typename _Tp, + formattable<_CharT> _Container, typename _Compare> + struct formatter<priority_queue<_Tp, _Container, _Compare>, _CharT> + { + private: + using __maybe_const_adaptor + = __conditional_t< + __format::__const_formattable_range<_Container, _CharT>, + const priority_queue<_Tp, _Container, _Compare>, + priority_queue<_Tp, _Container, _Compare>>; + + public: + // Standard declares this as template accepting unconstrained + // ParseContext type. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f.parse(__pc); } + + // Standard declares this as template accepting unconstrained + // FormatContext type. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__maybe_const_adaptor& __a, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f.format(__a.c, __fc); } + + private: + // Standard uses formatter<ref_view<_Container>, _CharT>. + range_formatter<_Tp, _CharT> _M_f; + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // __glibcxx_format_ranges + #endif /* _GLIBCXX_QUEUE */ diff --git a/libstdc++-v3/include/std/stack b/libstdc++-v3/include/std/stack index 5cea476..a57a5a0 100644 --- a/libstdc++-v3/include/std/stack +++ b/libstdc++-v3/include/std/stack @@ -61,11 +61,53 @@ #include <bits/requires_hosted.h> // containers -#include <deque> -#include <bits/stl_stack.h> - #define __glibcxx_want_adaptor_iterator_pair_constructor #define __glibcxx_want_containers_ranges #include <bits/version.h> +#include <deque> +#include <bits/stl_stack.h> + +#ifdef __glibcxx_format_ranges // C++ >= 23 && HOSTED +#include <bits/formatfwd.h> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + // Standard does not constrain accepted _CharT, we do so we can + // befriend specializations. + template<__format::__char _CharT, typename _Tp, + formattable<_CharT> _Container> + struct formatter<stack<_Tp, _Container>, _CharT> + { + private: + using __maybe_const_adaptor + = __conditional_t< + __format::__const_formattable_range<_Container, _CharT>, + const stack<_Tp, _Container>, stack<_Tp, _Container>>; + + public: + // Standard declares this as template accepting unconstrained + // ParseContext type. + constexpr typename basic_format_parse_context<_CharT>::iterator + parse(basic_format_parse_context<_CharT>& __pc) + { return _M_f.parse(__pc); } + + // Standard declares this as template accepting unconstrained + // FormatContext type. + template<typename _Out> + typename basic_format_context<_Out, _CharT>::iterator + format(__maybe_const_adaptor& __a, + basic_format_context<_Out, _CharT>& __fc) const + { return _M_f.format(__a.c, __fc); } + + private: + // Standard uses formatter<ref_view<_Container>, _CharT>. + range_formatter<_Tp, _CharT> _M_f; + }; +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // __glibcxx_format_ranges + + #endif /* _GLIBCXX_STACK */ diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index d2f91ad..0de08c0 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -297,7 +297,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // __cpp_lib_jthread #ifdef __cpp_lib_formatters // C++ >= 23 - template<typename _CharT> + // We deviate from the standard, that does not put requirements + // on _CharT here. + template<__format::__char _CharT> requires is_pointer_v<thread::native_handle_type> || is_integral_v<thread::native_handle_type> class formatter<thread::id, _CharT> @@ -307,6 +309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION parse(basic_format_parse_context<_CharT>& __pc) { __format::_Spec<_CharT> __spec{}; + __spec._M_align = __format::_Align_right; const auto __last = __pc.end(); auto __first = __pc.begin(); @@ -334,36 +337,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__finished()) return __first; - __throw_format_error("format error: invalid format-spec for " - "std::thread::id"); + std::__throw_format_error("format error: invalid format-spec for " + "std::thread::id"); } template<typename _Out> typename basic_format_context<_Out, _CharT>::iterator format(thread::id __id, basic_format_context<_Out, _CharT>& __fc) const { - basic_string_view<_CharT> __sv; - if constexpr (is_same_v<_CharT, char>) - __sv = "{}thread::id of a non-executing thread"; - else - __sv = L"{}thread::id of a non-executing thread"; - basic_string<_CharT> __str; + if (__id == thread::id()) - __sv.remove_prefix(2); - else { - using _FmtStr = __format::_Runtime_format_string<_CharT>; - // Convert non-void pointers to const void* for formatted output. - using __output_type - = __conditional_t<is_pointer_v<thread::native_handle_type>, - const void*, - thread::native_handle_type>; - auto __o = static_cast<__output_type>(__id._M_thread); - __sv = __str = std::format(_FmtStr(__sv.substr(0, 2)), __o); + const _CharT* __msg; + if constexpr (is_same_v<_CharT, char>) + __msg = "thread::id of a non-executing thread"; + else + __msg = L"thread::id of a non-executing thread"; + + __format::__formatter_str<_CharT> __formatter(_M_spec); + return __formatter.format(__msg, __fc); } - return __format::__write_padded_as_spec(__sv, __sv.size(), - __fc, _M_spec, - __format::_Align_right); + + using _HandleFormatter + = __conditional_t<is_pointer_v<thread::native_handle_type>, + __format::__formatter_ptr<_CharT>, + __format::__formatter_int<_CharT>>; + + _HandleFormatter __formatter(_M_spec); + return __formatter.format(__id._M_thread, __fc); } private: diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in index ea50496..930a489 100644 --- a/libstdc++-v3/src/c++23/std.cc.in +++ b/libstdc++-v3/src/c++23/std.cc.in @@ -1319,8 +1319,7 @@ export namespace std using std::format_to_n; using std::format_to_n_result; using std::formatted_size; -// FIXME __cpp_lib_format_ranges -#if __cplusplus > 202002L +#if __cpp_lib_format_ranges using std::formattable; #endif using std::formatter; @@ -1336,8 +1335,7 @@ export namespace std using std::wformat_context; using std::wformat_parse_context; using std::wformat_string; -// FIXME __cpp_lib_format_ranges -#ifdef __glibcxx_format_ranges +#ifdef __cpp_lib_format_ranges using std::format_kind; using std::range_format; using std::range_formatter; diff --git a/libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc b/libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc index a34b2ae..24aba99 100644 --- a/libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc +++ b/libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc @@ -18,7 +18,6 @@ // <http://www.gnu.org/licenses/>. // { dg-error "invalid use of incomplete type" "" { target *-*-* } 0 } -// { dg-error "invalid 'static_cast'" "" { target c++98_only } 0 } #include <locale> diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/48101_neg.cc index 2f2ea2a..d18195e 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/48101_neg.cc @@ -26,6 +26,5 @@ test01() } // { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 } -// { dg-prune-output "std::allocator<.* has no member named " } // { dg-prune-output "must have the same value_type as its allocator" } // { dg-prune-output "rebind_alloc" } diff --git a/libstdc++-v3/testsuite/23_containers/list/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/list/48101_neg.cc index 8b2e075..cc51705 100644 --- a/libstdc++-v3/testsuite/23_containers/list/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/48101_neg.cc @@ -26,5 +26,4 @@ test01() } // { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 } -// { dg-prune-output "std::allocator<.* has no member named " } // { dg-prune-output "must have the same value_type as its allocator" } diff --git a/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc index f0786cf..3cc0658 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc @@ -29,7 +29,6 @@ test01() // { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 } // { dg-error "comparison object must be invocable" "" { target *-*-* } 0 } -// { dg-prune-output "std::allocator<.* has no member named " } // { dg-prune-output "must have the same value_type as its allocator" } // { dg-prune-output "no match for call" } // { dg-prune-output "invalid conversion" } diff --git a/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc b/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc index e8dec72..fe38d1a 100644 --- a/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/set/48101_neg.cc @@ -29,7 +29,6 @@ test01() // { dg-error "non-const, non-volatile value_type" "" { target *-*-* } 0 } // { dg-error "comparison object must be invocable" "" { target *-*-* } 0 } -// { dg-prune-output "std::allocator<.* has no member named " } // { dg-prune-output "must have the same value_type as its allocator" } // { dg-prune-output "no match for call" } // { dg-prune-output "invalid conversion" } diff --git a/libstdc++-v3/testsuite/24_iterators/range_generators/lwg3899.cc b/libstdc++-v3/testsuite/24_iterators/range_generators/lwg3899.cc new file mode 100644 index 0000000..5a812ec --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/range_generators/lwg3899.cc @@ -0,0 +1,57 @@ +// { dg-do run { target c++23 } } + +// LWG 3899. +// co_yielding elements of an lvalue generator is unnecessarily inefficient + +#include <generator> +#include <memory_resource> +#include <testsuite_hooks.h> + +struct memory_resource : std::pmr::memory_resource +{ + std::size_t count = 0; + + void* do_allocate(std::size_t n, std::size_t a) override + { + count += n; + return std::pmr::new_delete_resource()->allocate(n, a); + } + + void do_deallocate(void* p, std::size_t n, std::size_t a) override + { + return std::pmr::new_delete_resource()->deallocate(p, n, a); + } + + bool do_is_equal(const std::pmr::memory_resource& mr) const noexcept override + { return this == &mr; } +}; + +std::pmr::generator<int> +f(std::allocator_arg_t, std::pmr::polymorphic_allocator<>, int init) +{ + co_yield init + 0; + co_yield init + 1; +} + +std::pmr::generator<int> +g(std::allocator_arg_t, std::pmr::polymorphic_allocator<> alloc) +{ + auto gen = f(std::allocator_arg, alloc, 0); + auto gen2 = f(std::allocator_arg, alloc, 2); + co_yield std::ranges::elements_of(std::move(gen), alloc); + co_yield std::ranges::elements_of(gen2, alloc); +} + +int +main() +{ + std::size_t counts[4]; + memory_resource mr; + for (auto d : g(std::allocator_arg , &mr)) + counts[d] = mr.count; + VERIFY(counts[0] != 0); + // No allocations after the first one: + VERIFY(counts[1] == counts[0]); + VERIFY(counts[2] == counts[0]); + VERIFY(counts[3] == counts[0]); +} diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc index 51c6ade..8cc3f78 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc @@ -8,6 +8,5 @@ int f(); std::packaged_task<const int&()> task(f); // { dg-error "dangling reference" "" { target { c++14_down } } 0 } // { dg-error "reference to temporary" "" { target { c++14_down } } 0 } -// { dg-error "no matching function" "" { target c++17 } 0 } -// { dg-error "enable_if" "" { target c++17 } 0 } // { dg-error "static assertion failed" "" { target c++17 } 0 } +// { dg-error "note: .*std::is_invocable_r" "" { target c++17 } 0 } diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc index 6ba1bb1..b3413c2 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc @@ -12,16 +12,16 @@ struct F { // Mandates: is_invocable_r_v<R, decay_t<F>&, ArgTypes...> is true. const F f; -std::packaged_task<void()> p(f); // { dg-error "here" "" { target c++17 } } -// { dg-error "static assertion failed" "" { target c++17 } 0 } -// { dg-error "invoke_r" "" { target *-*-* } 0 } -// { dg-prune-output "enable_if<false" } +std::packaged_task<void()> p(f); // { dg-error "here" } +// { dg-error "static assertion failed" "" { target *-*-* } 0 } +// { dg-error "note: .*std::is_invocable_r_v<void, " "" { target c++17 } 0 } // Only callable as rvalue struct Frv { int* operator()() && { return 0; } }; -std::packaged_task<int*()> p2(Frv{}); // { dg-error "here" "" { target c++17 } } +std::packaged_task<int*()> p2(Frv{}); // { dg-error "here" } +// { dg-error "note: .*std::is_invocable_r_v<int., " "" { target c++17 } 0 } // Only callable as non-const lvalue struct Fnc { diff --git a/libstdc++-v3/testsuite/30_threads/thread/id/output.cc b/libstdc++-v3/testsuite/30_threads/thread/id/output.cc index 94a6ff0..3d1dd38 100644 --- a/libstdc++-v3/testsuite/30_threads/thread/id/output.cc +++ b/libstdc++-v3/testsuite/30_threads/thread/id/output.cc @@ -118,8 +118,38 @@ test02() VERIFY( ws1.length() == len ); #endif + out.str(""); + out << i; + s1 = out.str(); + len = s1.size(); + out.str(""); + + // with width + s2 = std::format("{0:{1}}", i, len + 2); + VERIFY( s2 == (" " + s1) ); + // with align + width + s2 = std::format("{0:>{1}}", i, len + 2); + VERIFY( s2 == (" " + s1) ); + s2 = std::format("{0:<{1}}", i, len + 2); + VERIFY( s2 == (s1 + " ") ); + // with fill-and-align + width + s2 = std::format("{0:x^{1}}", i, len + 5); + VERIFY( s2 == ("xx" + s1 + "xxx") ); + +#ifdef _GLIBCXX_USE_WCHAR_T + static_assert( std::is_default_constructible_v<std::formatter<std::thread::id, wchar_t>> ); + ws1 = std::format(L"{}", i); + VERIFY( ws1.length() == len ); +#endif + t1.join(); t2.join(); + + static_assert( std::formattable<std::thread::id, char> ); + static_assert( std::formattable<std::thread::id, wchar_t> ); + static_assert( !std::formattable<std::thread::id, char16_t> ); + static_assert( !std::formattable<std::thread::id, int> ); + #elif __cplusplus >= 202302L # error "Feature-test macro for formatters has wrong value in <thread>" #endif diff --git a/libstdc++-v3/testsuite/std/format/debug.cc b/libstdc++-v3/testsuite/std/format/debug.cc index 71bb7f4..d3402f8 100644 --- a/libstdc++-v3/testsuite/std/format/debug.cc +++ b/libstdc++-v3/testsuite/std/format/debug.cc @@ -2,6 +2,7 @@ // { dg-options "-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32BE -DUNICODE_ENC" { target be } } // { dg-do run { target c++23 } } // { dg-add-options no_pch } +// { dg-timeout-factor 2 } #include <format> #include <testsuite_hooks.h> @@ -96,7 +97,7 @@ test_extended_ascii() res = fdebug(in); VERIFY( res == WIDEN(R"("Åëÿ")") ); - static constexpr bool __test_characters + static constexpr bool __test_characters #if UNICODE_ENC = sizeof(_CharT) >= 2; #else // ISO8859-1 @@ -114,11 +115,11 @@ test_extended_ascii() } } -#if UNICODE_ENC template<typename _CharT> void test_unicode_escapes() { +#if UNICODE_ENC std::basic_string<_CharT> res; const auto in = WIDEN( @@ -160,12 +161,14 @@ test_unicode_escapes() res = fdebug(in[5]); VERIFY( res == WIDEN("'\U0001f984'") ); } +#endif // UNICODE_ENC } template<typename _CharT> void test_grapheme_extend() { +#if UNICODE_ENC std::basic_string<_CharT> res; const auto vin = WIDEN("o\u0302\u0323"); @@ -184,12 +187,14 @@ test_grapheme_extend() res = fdebug(in[1]); VERIFY( res == WIDEN(R"('\u{302}')") ); } +#endif // UNICODE_ENC } template<typename _CharT> void test_replacement_char() { +#if UNICODE_ENC std::basic_string<_CharT> repl = WIDEN("\uFFFD"); std::basic_string<_CharT> res = fdebug(repl); VERIFY( res == WIDEN("\"\uFFFD\"") ); @@ -197,11 +202,13 @@ test_replacement_char() repl = WIDEN("\uFFFD\uFFFD"); res = fdebug(repl); VERIFY( res == WIDEN("\"\uFFFD\uFFFD\"") ); +#endif // UNICODE_ENC } void test_ill_formed_utf8_seq() { +#if UNICODE_ENC std::string_view seq = "\xf0\x9f\xa6\x84"; // \U0001F984 std::string res; @@ -233,11 +240,13 @@ test_ill_formed_utf8_seq() VERIFY( res == R"('\x{84}')" ); res = fdebug(seq.substr(3, 1)); VERIFY( res == R"("\x{84}")" ); +#endif // UNICODE_ENC } void test_ill_formed_utf32() { +#if UNICODE_ENC std::wstring res; wchar_t ic1 = static_cast<wchar_t>(0xff'ffff); @@ -255,8 +264,8 @@ test_ill_formed_utf32() std::wstring is2(1, ic2); res = fdebug(is2); VERIFY( res == LR"("\x{ffffffff}")" ); -} #endif // UNICODE_ENC +} template<typename _CharT> void @@ -331,6 +340,375 @@ test_prec() #endif // UNICODE_ENC } +bool strip_quote(std::string_view& v) +{ + if (!v.starts_with('"')) + return false; + v.remove_prefix(1); + return true; +} + +bool strip_quotes(std::string_view& v) +{ + if (!v.starts_with('"') || !v.ends_with('"')) + return false; + v.remove_prefix(1); + v.remove_suffix(1); + return true; +} + +bool strip_prefix(std::string_view& v, size_t n, char c) +{ + size_t pos = v.find_first_not_of(c); + if (pos == std::string_view::npos) + pos = v.size(); + if (pos != n) + return false; + v.remove_prefix(n); + return true; +} + +void test_padding() +{ + std::string res; + std::string_view resv; + + // width and size are 26 + std::string in = "abcdefghijklmnopqrstuvwxyz"; + in += in; // width and size are 52 + in += in; // width and size are 104 + in += in; // width and size are 208 + in += in; // width and size are 416 + std::string_view inv = in; + + resv = res = std::format("{}", in); + VERIFY( resv == inv ); + + resv = res = std::format("{:.500}", in); + VERIFY( resv == inv ); + + resv = res = std::format("{:.400}", in); + VERIFY( resv == inv.substr(0, 400) ); + + resv = res = std::format("{:.200}", in); + VERIFY( resv == inv.substr(0, 200) ); + + resv = res = std::format("{:.10}", in); + VERIFY( resv == inv.substr(0, 10) ); + + resv = res = std::format("{:.0}", in); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>20}", in); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>20.500}", in); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>20.400}", in); + VERIFY( resv == inv.substr(0, 400) ); + + resv = res = std::format("{:*>20.200}", in); + VERIFY( resv == inv.substr(0, 200) ); + + resv = res = std::format("{:*>20.10}", in); + VERIFY( strip_prefix(resv, 10, '*') ); + VERIFY( resv == inv.substr(0, 10) ); + + resv = res = std::format("{:*>20.0}", in); + VERIFY( strip_prefix(resv, 20, '*') ); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>450}", in); + VERIFY( strip_prefix(resv, 34, '*') ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>450.500}", in); + VERIFY( strip_prefix(resv, 34, '*') ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>450.420}", in); + VERIFY( strip_prefix(resv, 34, '*') ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>450.400}", in); + VERIFY( strip_prefix(resv, 50, '*') ); + VERIFY( resv == inv.substr(0, 400) ); + + resv = res = std::format("{:*>450.200}", in); + VERIFY( strip_prefix(resv, 250, '*') ); + VERIFY( resv == inv.substr(0, 200) ); + + resv = res = std::format("{:*>450.10}", in); + VERIFY( strip_prefix(resv, 440, '*') ); + VERIFY( resv == inv.substr(0, 10) ); + + resv = res = std::format("{:*>450.0}", in); + VERIFY( strip_prefix(resv, 450, '*') ); + VERIFY( resv == "" ); + + resv = res = std::format("{:?}", in); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:.500?}", in); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:.400?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 399) ); + + resv = res = std::format("{:.200?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 199) ); + + resv = res = std::format("{:.10?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 9) ); + + resv = res = std::format("{:.1?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == "" ); + + resv = res = std::format("{:.0?}", in); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>20?}", in); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>20.500?}", in); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>20.400?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 399) ); + + resv = res = std::format("{:*>20.200?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 199) ); + + resv = res = std::format("{:*>20.10?}", in); + VERIFY( strip_prefix(resv, 10, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 9) ); + + resv = res = std::format("{:*>20.1?}", in); + VERIFY( strip_prefix(resv, 19, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>20.0?}", in); + VERIFY( strip_prefix(resv, 20, '*') ); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>450?}", in); + VERIFY( strip_prefix(resv, 32, '*') ); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>450.500?}", in); + VERIFY( strip_prefix(resv, 32, '*') ); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>450.420?}", in); + VERIFY( strip_prefix(resv, 32, '*') ); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>450.400?}", in); + VERIFY( strip_prefix(resv, 50, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 399) ); + + resv = res = std::format("{:*>450.200?}", in); + VERIFY( strip_prefix(resv, 250, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 199) ); + + resv = res = std::format("{:*>450.10?}", in); + VERIFY( strip_prefix(resv, 440, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 9) ); + + resv = res = std::format("{:*>450.1?}", in); + VERIFY( strip_prefix(resv, 449, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>450.0?}", in); + VERIFY( strip_prefix(resv, 450, '*') ); + VERIFY( resv == "" ); + +#if UNICODE_ENC + // width is 3, size is 15 + in = "o\u0302\u0323i\u0302\u0323u\u0302\u0323"; + in += in; // width is 6, size is 30 + in += in; // width is 12, size is 60 + in += in; // width is 24, size is 120 + in += in; // width is 48, size is 240 + in += in; // width is 96, size is 480 + in += in; // width is 192, size is 960 + inv = in; + + resv = res = std::format("{:}", in); + VERIFY( resv == inv ); + + resv = res = std::format("{:.200}", in); + VERIFY( resv == inv ); + + resv = res = std::format("{:.96}", in); + VERIFY( resv == inv.substr(0, 480) ); + + resv = res = std::format("{:.12}", in); + VERIFY( resv == inv.substr(0, 60) ); + + resv = res = std::format("{:.3}", in); + VERIFY( resv == inv.substr(0, 15) ); + + resv = res = std::format("{:.0}", in); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>10}", in); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>10.200}", in); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>10.96}", in); + VERIFY( resv == inv.substr(0, 480) ); + + resv = res = std::format("{:*>10.12}", in); + VERIFY( resv == inv.substr(0, 60) ); + + resv = res = std::format("{:*>10.3}", in); + VERIFY( strip_prefix(resv, 7, '*') ); + VERIFY( resv == inv.substr(0, 15) ); + + resv = res = std::format("{:*>10.0}", in); + VERIFY( strip_prefix(resv, 10, '*') ); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>240s}", in); + VERIFY( strip_prefix(resv, 48, '*') ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>240.200s}", in); + VERIFY( strip_prefix(resv, 48, '*') ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>240.96s}", in); + VERIFY( strip_prefix(resv, 144, '*') ); + VERIFY( resv == inv.substr(0, 480) ); + + resv = res = std::format("{:*>240.12}", in); + VERIFY( strip_prefix(resv, 228, '*') ); + VERIFY( resv == inv.substr(0, 60) ); + + resv = res = std::format("{:*>240.3s}", in); + VERIFY( strip_prefix(resv, 237, '*') ); + VERIFY( resv == inv.substr(0, 15) ); + + resv = res = std::format("{:*>240.0s}", in); + VERIFY( strip_prefix(resv, 240, '*') ); + VERIFY( resv == "" ); + + resv = res = std::format("{:?}", in); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:.200?}", in); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:.97?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 480) ); + + resv = res = std::format("{:.13?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 60) ); + + resv = res = std::format("{:.4?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 15) ); + + resv = res = std::format("{:.1?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == "" ); + + resv = res = std::format("{:.0?}", in); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>10?}", in); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>10.200?}", in); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>10.97?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 480) ); + + resv = res = std::format("{:*>10.13?}", in); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 60) ); + + resv = res = std::format("{:*>10.4?}", in); + VERIFY( strip_prefix(resv, 6, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 15) ); + + resv = res = std::format("{:*>10.1?}", in); + VERIFY( strip_prefix(resv, 9, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>10.0?}", in); + VERIFY( strip_prefix(resv, 10, '*') ); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>240?}", in); + VERIFY( strip_prefix(resv, 46, '*') ); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>240.200?}", in); + VERIFY( strip_prefix(resv, 46, '*') ); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == inv ); + + resv = res = std::format("{:*>240.97?}", in); + VERIFY( strip_prefix(resv, 143, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 480) ); + + resv = res = std::format("{:*>240.13?}", in); + VERIFY( strip_prefix(resv, 227, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 60) ); + + resv = res = std::format("{:*>240.4?}", in); + VERIFY( strip_prefix(resv, 236, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == inv.substr(0, 15) ); + + resv = res = std::format("{:*>240.1?}", in); + VERIFY( strip_prefix(resv, 239, '*') ); + VERIFY( strip_quote(resv) ); + VERIFY( resv == "" ); + + resv = res = std::format("{:*>240.0?}", in); + VERIFY( strip_prefix(resv, 240, '*') ); + VERIFY( resv == "" ); +#endif // UNICODE_ENC +} + void test_char_as_wchar() { std::wstring res; @@ -435,7 +813,6 @@ int main() test_extended_ascii<char>(); test_extended_ascii<wchar_t>(); -#if UNICODE_ENC test_unicode_escapes<char>(); test_unicode_escapes<wchar_t>(); test_grapheme_extend<char>(); @@ -444,12 +821,13 @@ int main() test_replacement_char<wchar_t>(); test_ill_formed_utf8_seq(); test_ill_formed_utf32(); -#endif // UNICODE_ENC test_fill<char>(); test_fill<wchar_t>(); test_prec<char>(); test_prec<wchar_t>(); + test_padding(); + test_formatters_c(); } diff --git a/libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc b/libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc index 1f3edc9..07e63af 100644 --- a/libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc +++ b/libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc @@ -18,7 +18,7 @@ void test_lwg3944() std::format(L"{}", "hello"); // { dg-error "here" } std::format(L"{}", std::string_view("hello")); // { dg-error "here" } std::format(L"{}", std::string("hello")); // { dg-error "here" } -#ifdef __glibcxx_format_ranges +#ifdef __cpp_lib_format_ranges // LWG 3944 does not change this, it's still valid. std::format(L"{}", std::vector{'h', 'e', 'l', 'l', 'o'}); #endif diff --git a/libstdc++-v3/testsuite/std/format/parse_ctx.cc b/libstdc++-v3/testsuite/std/format/parse_ctx.cc index b338ac7..b5dd7cd 100644 --- a/libstdc++-v3/testsuite/std/format/parse_ctx.cc +++ b/libstdc++-v3/testsuite/std/format/parse_ctx.cc @@ -108,7 +108,7 @@ is_std_format_spec_for(std::string_view spec) } } -#if __glibcxx_format_ranges +#if __cpp_lib_format_ranges constexpr bool escaped_strings_supported = true; #else constexpr bool escaped_strings_supported = false; diff --git a/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc b/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc new file mode 100644 index 0000000..daa73aa --- /dev/null +++ b/libstdc++-v3/testsuite/std/format/ranges/adaptors.cc @@ -0,0 +1,156 @@ +// { dg-do run { target c++23 } } +// { dg-timeout-factor 2 } + +#include <format> +#include <queue> +#include <stack> +#include <testsuite_hooks.h> + +template<typename... Args> +bool +is_format_string_for(const char* str, Args&&... args) +{ + try { + (void) std::vformat(str, std::make_format_args(args...)); + return true; + } catch (const std::format_error&) { + return false; + } +} + +#define WIDEN_(C, S) ::std::__format::_Widen<C>(S, L##S) +#define WIDEN(S) WIDEN_(_CharT, S) + +template<template<typename Tp> class Adaptor> +void +test_format_string() +{ + Adaptor<int> q; + VERIFY( !is_format_string_for("{:?}", q) ); + VERIFY( !is_format_string_for("{:P}", q) ); + + // width needs to be integer type + VERIFY( !is_format_string_for("{:{}}", q, 1.0f) ); +} + +struct NoFormat +{ + friend auto operator<=>(NoFormat, NoFormat) = default; +}; + +struct MutFormat +{ + MutFormat() = default; + MutFormat(int p) : x(p) {} + + int x; + friend auto operator<=>(MutFormat, MutFormat) = default; +}; + +template<typename CharT> +struct std::formatter<MutFormat, CharT> + : std::formatter<int, CharT> +{ + template<typename Out> + Out format(MutFormat& mf, basic_format_context<Out, CharT>& ctx) const + { return std::formatter<int, CharT>::format(mf.x, ctx); } +}; + +template<typename T> +struct NotFormattableCont : std::vector<T> +{ + using std::vector<T>::vector; +}; + +template<typename T> +constexpr auto std::format_kind<NotFormattableCont<T>> + = std::range_format::disabled; + +template<typename _CharT, + template<typename Tp, typename Cont = std::vector<Tp>> class Adaptor> +void +test_output() +{ + const std::vector<int> v{3, 2, 1}; + std::basic_string<_CharT> res; + Adaptor<int, std::vector<int>> q(std::from_range, v); + + res = std::format(WIDEN("{}"), q); + VERIFY( res == WIDEN("[3, 2, 1]") ); + + res = std::format(WIDEN("{}"), std::as_const(q)); + VERIFY( res == WIDEN("[3, 2, 1]") ); + + res = std::format(WIDEN("{:n:#x}"), q); + VERIFY( res == WIDEN("0x3, 0x2, 0x1") ); + + res = std::format(WIDEN("{:=^23:#04x}"), q); + VERIFY( res == WIDEN("==[0x03, 0x02, 0x01]===") ); + + // Sequence output is always used + Adaptor<_CharT, std::basic_string<_CharT>> qs( + std::from_range, + std::basic_string_view<_CharT>(WIDEN("321"))); + + res = std::format(WIDEN("{}"), qs); + VERIFY( res == WIDEN("['3', '2', '1']") ); + + res = std::format(WIDEN("{::}"), std::as_const(qs)); + VERIFY( res == WIDEN("[3, 2, 1]") ); + + res = std::format(WIDEN("{:?s}"), qs); + VERIFY( res == WIDEN(R"("321")") ); + + Adaptor<int, std::deque<int>> qd(std::from_range, v); + + res = std::format(WIDEN("{}"), qd); + VERIFY( res == WIDEN("[3, 2, 1]") ); + + res = std::format(WIDEN("{}"), std::as_const(qd)); + VERIFY( res == WIDEN("[3, 2, 1]") ); + + Adaptor<MutFormat> mq(std::from_range, v); + + res = std::format(WIDEN("{}"), mq); + VERIFY( res == WIDEN("[3, 2, 1]") ); + + static_assert(!std::formattable<const Adaptor<MutFormat>, _CharT>); + + static_assert(!std::formattable<Adaptor<NoFormat>, _CharT>); + static_assert(!std::formattable<const Adaptor<NoFormat>, _CharT>); + + // Formatter check if container is formattable, not container elements. + static_assert(!std::formattable<Adaptor<int, NotFormattableCont<int>>, _CharT>); +} + +template<template<typename Tp, typename Cont = std::vector<Tp>> class Adaptor> +void +test_adaptor() +{ + test_format_string<Adaptor>(); + test_output<char, Adaptor>(); + test_output<wchar_t, Adaptor>(); + + static_assert(!std::formattable<Adaptor<int>, int>); + static_assert(!std::formattable<Adaptor<int>, char32_t>); +} + +template<typename _CharT> +void +test_compare() +{ + const std::vector<int> v{3, 2, 1}; + std::basic_string<_CharT> res; + std::priority_queue<int, std::vector<int>, std::greater<>> q( + std::from_range, v); + + res = std::format(WIDEN("{}"), q); + VERIFY( res == WIDEN("[1, 2, 3]") ); +} + +int main() +{ + test_adaptor<std::queue>(); + test_adaptor<std::priority_queue>(); + test_compare<char>(); +} diff --git a/libstdc++-v3/testsuite/std/format/ranges/feature_test.cc b/libstdc++-v3/testsuite/std/format/ranges/feature_test.cc new file mode 100644 index 0000000..80d2cea --- /dev/null +++ b/libstdc++-v3/testsuite/std/format/ranges/feature_test.cc @@ -0,0 +1,9 @@ +// { dg-do preprocess { target c++23 } } + +#include <format> + +#ifndef __cpp_lib_format_ranges +# error "Feature-test macro __cpp_lib_format_ranges missing in <format>" +#elif __cpp_lib_format_ranges != 202207L +# error "Feature-test macro __cpp_lib_format_ranges has wrong value in <format>" +#endif diff --git a/libstdc++-v3/testsuite/std/format/ranges/sequence.cc b/libstdc++-v3/testsuite/std/format/ranges/sequence.cc index f05f6ec..75fe4c1 100644 --- a/libstdc++-v3/testsuite/std/format/ranges/sequence.cc +++ b/libstdc++-v3/testsuite/std/format/ranges/sequence.cc @@ -1,4 +1,5 @@ // { dg-do run { target c++23 } } +// { dg-options "-fexec-charset=UTF-8" } // { dg-timeout-factor 2 } #include <array> @@ -6,6 +7,7 @@ #include <list> #include <ranges> #include <span> +#include <string> #include <testsuite_hooks.h> #include <testsuite_iterators.h> #include <vector> @@ -199,9 +201,123 @@ test_nested() VERIFY( res == "+[01, 02, 11, 12]+" ); } +bool strip_quote(std::string_view& v) +{ + if (!v.starts_with('"')) + return false; + v.remove_prefix(1); + return true; +} + +bool strip_prefix(std::string_view& v, std::string_view expected, bool quoted = false) +{ + if (quoted && !strip_quote(v)) + return false; + if (!v.starts_with(expected)) + return false; + v.remove_prefix(expected.size()); + if (quoted && !strip_quote(v)) + return false; + return true; +} + +bool strip_squares(std::string_view& v) +{ + if (!v.starts_with('[') || !v.ends_with(']')) + return false; + v.remove_prefix(1); + v.remove_suffix(1); + return true; +} + +bool strip_prefix(std::string_view& v, size_t n, char c) +{ + size_t pos = v.find_first_not_of(c); + if (pos == std::string_view::npos) + pos = v.size(); + if (pos != n) + return false; + v.remove_prefix(n); + return true; +} + +void test_padding() +{ + std::string res; + std::string_view resv; + + // width is 3, size is 15 + std::string in = "o\u0302\u0323i\u0302\u0323u\u0302\u0323"; + in += in; // width is 6, size is 30 + in += in; // width is 12, size is 60 + in += in; // width is 24, size is 120 + in += in; // width is 48, size is 240 + // width is 192, size is 960 + std::vector<std::string> const vs{in, in, in, in}; + + auto const check_elems = [=](std::string_view& v, bool quoted) + { + VERIFY( strip_prefix(v, in, quoted) ); + VERIFY( strip_prefix(v, ", ", false) ); + VERIFY( strip_prefix(v, in, quoted) ); + VERIFY( strip_prefix(v, ", ", false) ); + VERIFY( strip_prefix(v, in, quoted) ); + VERIFY( strip_prefix(v, ", ", false) ); + VERIFY( strip_prefix(v, in, quoted) ); + return v.empty(); + }; + + resv = res = std::format("{}", vs); + VERIFY( strip_squares(resv) ); + VERIFY( check_elems(resv, true) ); + + resv = res = std::format("{:n}", vs); + VERIFY( check_elems(resv, true) ); + + resv = res = std::format("{::}", vs); + VERIFY( strip_squares(resv) ); + VERIFY( check_elems(resv, false) ); + + resv = res = std::format("{:n:}", vs); + VERIFY( check_elems(resv, false) ); + + resv = res = std::format("{:*>10}", vs); + VERIFY( strip_squares(resv) ); + VERIFY( check_elems(resv, true) ); + + resv = res = std::format("{:*>10n}", vs); + VERIFY( check_elems(resv, true) ); + + resv = res = std::format("{:*>10:}", vs); + VERIFY( strip_squares(resv) ); + VERIFY( check_elems(resv, false) ); + + resv = res = std::format("{:*>10n:}", vs); + VERIFY( check_elems(resv, false) ); + + resv = res = std::format("{:*>240}", vs); + VERIFY( strip_prefix(resv, 32, '*') ); + VERIFY( strip_squares(resv) ); + VERIFY( check_elems(resv, true) ); + + resv = res = std::format("{:*>240n}", vs); + VERIFY( strip_prefix(resv, 34, '*') ); + VERIFY( check_elems(resv, true) ); + + resv = res = std::format("{:*>240:}", vs); + VERIFY( strip_prefix(resv, 40, '*') ); + VERIFY( strip_squares(resv) ); + VERIFY( check_elems(resv, false) ); + + resv = res = std::format("{:*>240n:}", vs); + VERIFY( strip_prefix(resv, 42, '*') ); + VERIFY( check_elems(resv, false) ); +} + int main() { test_format_string(); test_outputs(); test_nested(); + test_padding(); } diff --git a/libstdc++-v3/testsuite/std/format/ranges/string.cc b/libstdc++-v3/testsuite/std/format/ranges/string.cc index cf39aa6..cebdd53 100644 --- a/libstdc++-v3/testsuite/std/format/ranges/string.cc +++ b/libstdc++-v3/testsuite/std/format/ranges/string.cc @@ -1,7 +1,9 @@ // { dg-do run { target c++23 } } +// { dg-options "-fexec-charset=UTF-8" } // { dg-timeout-factor 2 } #include <format> +#include <forward_list> #include <span> #include <testsuite_hooks.h> #include <testsuite_iterators.h> @@ -218,6 +220,67 @@ test_nested() VERIFY( std::format("{::?s}", vv) == R"(["str1", "str2"])" ); } +bool strip_quotes(std::string_view& v) +{ + if (!v.starts_with('"') || !v.ends_with('"')) + return false; + v.remove_prefix(1); + v.remove_suffix(1); + return true; +} + +bool strip_prefix(std::string_view& v, size_t n, char c) +{ + size_t pos = v.find_first_not_of(c); + if (pos == std::string_view::npos) + pos = v.size(); + if (pos != n) + return false; + v.remove_prefix(n); + return true; +} + + +void test_padding() +{ + std::string res; + std::string_view resv; + + // width is 3, size is 15 + std::string in = "o\u0302\u0323i\u0302\u0323u\u0302\u0323"; + in += in; // width is 6, size is 30 + in += in; // width is 12, size is 60 + in += in; // width is 24, size is 120 + in += in; // width is 48, size is 240 + in += in; // width is 96, size is 480 + in += in; // width is 192, size is 960 + + std::forward_list<char> lc(std::from_range, in); + + resv = res = std::format("{:s}", lc); + VERIFY( resv == in ); + + resv = res = std::format("{:*>10s}", lc); + VERIFY( resv == in ); + + resv = res = std::format("{:*>240s}", lc); + VERIFY( strip_prefix(resv, 48, '*') ); + VERIFY( resv == in ); + + resv = res = std::format("{:?s}", lc); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == in ); + + resv = res = std::format("{:*>10?s}", lc); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == in ); + + resv = res = std::format("{:*>240?s}", lc); + VERIFY( strip_prefix(resv, 46, '*') ); + VERIFY( strip_quotes(resv) ); + VERIFY( resv == in ); +} + int main() { test_format_string(); diff --git a/libstdc++-v3/testsuite/std/format/string.cc b/libstdc++-v3/testsuite/std/format/string.cc index 76614d4..ee987a1 100644 --- a/libstdc++-v3/testsuite/std/format/string.cc +++ b/libstdc++-v3/testsuite/std/format/string.cc @@ -62,7 +62,7 @@ test_indexing() VERIFY( ! is_format_string_for("{} {0}", 1) ); } -#if __glibcxx_format_ranges +#if __cpp_lib_format_ranges constexpr bool escaped_strings_supported = true; #else constexpr bool escaped_strings_supported = false; diff --git a/libstdc++-v3/testsuite/std/format/tuple.cc b/libstdc++-v3/testsuite/std/format/tuple.cc index 62f9d29..ff0359b 100644 --- a/libstdc++-v3/testsuite/std/format/tuple.cc +++ b/libstdc++-v3/testsuite/std/format/tuple.cc @@ -1,4 +1,6 @@ // { dg-do run { target c++23 } } +// { dg-options "-fexec-charset=UTF-8" } +// { dg-timeout-factor 2 } #include <format> #include <string> @@ -250,10 +252,101 @@ void test_nested() VERIFY( res == R"((): (1, "abc"))" ); } +bool strip_quote(std::string_view& v) +{ + if (!v.starts_with('"')) + return false; + v.remove_prefix(1); + return true; +} + +bool strip_prefix(std::string_view& v, std::string_view expected, bool quoted = false) +{ + if (quoted && !strip_quote(v)) + return false; + if (!v.starts_with(expected)) + return false; + v.remove_prefix(expected.size()); + if (quoted && !strip_quote(v)) + return false; + return true; +} + +bool strip_parens(std::string_view& v) +{ + if (!v.starts_with('(') || !v.ends_with(')')) + return false; + v.remove_prefix(1); + v.remove_suffix(1); + return true; +} + +bool strip_prefix(std::string_view& v, size_t n, char c) +{ + size_t pos = v.find_first_not_of(c); + if (pos == std::string_view::npos) + pos = v.size(); + if (pos != n) + return false; + v.remove_prefix(n); + return true; +} + +void test_padding() +{ + std::string res; + std::string_view resv; + + // width is 3, size is 15 + std::string in = "o\u0302\u0323i\u0302\u0323u\u0302\u0323"; + in += in; // width is 6, size is 30 + in += in; // width is 12, size is 60 + in += in; // width is 24, size is 120 + in += in; // width is 48, size is 240 + // width is 192, size is 960 + auto const ts = std::make_tuple(in, in, in, in); + + auto const check_elems = [=](std::string_view& v) + { + VERIFY( strip_prefix(v, in, true) ); + VERIFY( strip_prefix(v, ", ", false) ); + VERIFY( strip_prefix(v, in, true) ); + VERIFY( strip_prefix(v, ", ", false) ); + VERIFY( strip_prefix(v, in, true) ); + VERIFY( strip_prefix(v, ", ", false) ); + VERIFY( strip_prefix(v, in, true) ); + return v.empty(); + }; + + resv = res = std::format("{}", ts); + VERIFY( strip_parens(resv) ); + VERIFY( check_elems(resv) ); + + resv = res = std::format("{:n}", ts); + VERIFY( check_elems(resv) ); + + resv = res = std::format("{:*>10}", ts); + VERIFY( strip_parens(resv) ); + VERIFY( check_elems(resv) ); + + resv = res = std::format("{:*>10n}", ts); + VERIFY( check_elems(resv) ); + + resv = res = std::format("{:*>240}", ts); + VERIFY( strip_prefix(resv, 32, '*') ); + VERIFY( strip_parens(resv) ); + VERIFY( check_elems(resv) ); + + resv = res = std::format("{:*>240n}", ts); + VERIFY( strip_prefix(resv, 34, '*') ); + VERIFY( check_elems(resv) ); +} + int main() { test_format_string(); test_outputs<char>(); test_outputs<wchar_t>(); test_nested(); + test_padding(); } diff --git a/maintainer-scripts/gcc_release b/maintainer-scripts/gcc_release index 2ead4a7..c7af3fd 100755 --- a/maintainer-scripts/gcc_release +++ b/maintainer-scripts/gcc_release @@ -141,7 +141,7 @@ build_sources() { "in gcc-${RELEASE_MAJOR}/index.html" sed -n -e "/^${thischanges}/,/^${previndex}/p" NEWS |\ - grep -q "^[[:blank:]]*GCC ${RELEASE_MAJOR}.${RELEASE_MINOR}" ||\ + grep -q "^[[:blank:]]*\(\[[0-9]\{1,\}\][[:blank:]]*\)\{0,1\}GCC ${RELEASE_MAJOR}.${RELEASE_MINOR}" ||\ error "GCC ${RELEASE_MAJOR}.${RELEASE_MINOR} not mentioned "\ "in gcc-${RELEASE_MAJOR}/changes.html" |