aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/gennews1
-rw-r--r--gcc/ChangeLog138
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/c-family/c-opts.cc6
-rw-r--r--gcc/cobol/ChangeLog17
-rw-r--r--gcc/cobol/genapi.cc99
-rw-r--r--gcc/cobol/genutil.cc779
-rw-r--r--gcc/common.opt3
-rw-r--r--gcc/common/config/riscv/riscv-common.cc31
-rw-r--r--gcc/config/gcn/gcn.cc6
-rw-r--r--gcc/config/i386/i386.cc43
-rw-r--r--gcc/config/s390/s390.cc33
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/lambda.cc41
-rw-r--r--gcc/cp/pt.cc10
-rw-r--r--gcc/fortran/ChangeLog10
-rw-r--r--gcc/fortran/trans-decl.cc6
-rw-r--r--gcc/fortran/trans-expr.cc10
-rw-r--r--gcc/ipa-icf.cc15
-rw-r--r--gcc/ipa-icf.h5
-rw-r--r--gcc/m2/ChangeLog36
-rw-r--r--gcc/modulo-sched.cc8
-rw-r--r--gcc/po/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog94
-rw-r--r--gcc/testsuite/cobol.dg/group1/declarative_1.cob6
-rw-r--r--gcc/testsuite/cobol.dg/group2/88_level_with_FALSE_IS_clause.cob19
-rw-r--r--gcc/testsuite/cobol.dg/group2/88_level_with_FILLER.cob20
-rw-r--r--gcc/testsuite/cobol.dg/group2/88_level_with_THRU.cob86
-rw-r--r--gcc/testsuite/cobol.dg/group2/ADD_CORRESPONDING.cob39
-rw-r--r--gcc/testsuite/cobol.dg/group2/ADD_SUBTRACT_CORR_mixed_fix___float.cob33
-rw-r--r--gcc/testsuite/cobol.dg/group2/ADD_SUBTRACT_CORR_mixed_fix___float.out4
-rw-r--r--gcc/testsuite/cobol.dg/group2/ALPHABETIC-LOWER_test.cob23
-rw-r--r--gcc/testsuite/cobol.dg/group2/ALPHABETIC-UPPER_test.cob23
-rw-r--r--gcc/testsuite/cobol.dg/group2/ALPHABETIC_test.cob23
-rw-r--r--gcc/testsuite/cobol.dg/group2/BLANK_WHEN_ZERO.cob16
-rw-r--r--gcc/testsuite/cobol.dg/group2/BLANK_WHEN_ZERO.out4
-rw-r--r--gcc/testsuite/cobol.dg/group2/Check_for_equality_of_COMP-1___COMP-2.cob106
-rw-r--r--gcc/testsuite/cobol.dg/group2/Compare_COMP-2_with_floating-point_literal.cob43
-rw-r--r--gcc/testsuite/cobol.dg/group2/Contained_program_visibility__3_.cob42
-rw-r--r--gcc/testsuite/cobol.dg/group2/Contained_program_visibility__4_.cob46
-rw-r--r--gcc/testsuite/cobol.dg/group2/Contained_program_visibility__4_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__1_.cob15
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__1_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__2_.cob16
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__2_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__3_.cob16
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__3_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__4_.cob17
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__4_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__5_.cob15
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__5_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__6_.cob14
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__6_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__7_.cob19
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__7_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__8_.cob19
-rw-r--r--gcc/testsuite/cobol.dg/group2/Context_sensitive_words__8_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/DEBUG_Line.cob16
-rw-r--r--gcc/testsuite/cobol.dg/group2/DEBUG_Line.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/DISPLAY_and_assignment_NumericDisplay.cob82
-rw-r--r--gcc/testsuite/cobol.dg/group2/DISPLAY_and_assignment_NumericDisplay.out37
-rw-r--r--gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_MOVE_statement.cob38
-rw-r--r--gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_MOVE_statement.out8
-rw-r--r--gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_VALUE_clause.cob31
-rw-r--r--gcc/testsuite/cobol.dg/group2/DISPLAY_data_items_with_VALUE_clause.out8
-rw-r--r--gcc/testsuite/cobol.dg/group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.cob24
-rw-r--r--gcc/testsuite/cobol.dg/group2/DISPLAY_literals__DECIMAL-POINT_is_COMMA.out7
-rw-r--r--gcc/testsuite/cobol.dg/group2/GLOBAL_FD__1_.cob42
-rw-r--r--gcc/testsuite/cobol.dg/group2/GLOBAL_FD__2_.cob42
-rw-r--r--gcc/testsuite/cobol.dg/group2/GLOBAL_FD__3_.cob41
-rw-r--r--gcc/testsuite/cobol.dg/group2/GLOBAL_FD__4_.cob41
-rw-r--r--gcc/testsuite/cobol.dg/group2/GLOBAL_at_lower_level.cob37
-rw-r--r--gcc/testsuite/cobol.dg/group2/GLOBAL_at_lower_level.out4
-rw-r--r--gcc/testsuite/cobol.dg/group2/GLOBAL_at_same_level.cob37
-rw-r--r--gcc/testsuite/cobol.dg/group2/GLOBAL_at_same_level.out4
-rw-r--r--gcc/testsuite/cobol.dg/group2/Hexadecimal_literal.cob15
-rw-r--r--gcc/testsuite/cobol.dg/group2/Hexadecimal_literal.out2
-rw-r--r--gcc/testsuite/cobol.dg/group2/MULTIPLY_BY_literal_in_INITIAL_program.cob15
-rw-r--r--gcc/testsuite/cobol.dg/group2/Named_conditionals_-_fixed__float__and_alphabetic.cob69
-rw-r--r--gcc/testsuite/cobol.dg/group2/Named_conditionals_-_fixed__float__and_alphabetic.out13
-rw-r--r--gcc/testsuite/cobol.dg/group2/Numeric_operations__1_.cob35
-rw-r--r--gcc/testsuite/cobol.dg/group2/Numeric_operations__2_.cob292
-rw-r--r--gcc/testsuite/cobol.dg/group2/Numeric_operations__3_.cob292
-rw-r--r--gcc/testsuite/cobol.dg/group2/Numeric_operations__4_.cob292
-rw-r--r--gcc/testsuite/cobol.dg/group2/Numeric_operations__5_.cob292
-rw-r--r--gcc/testsuite/cobol.dg/group2/Numeric_operations__7_.cob283
-rw-r--r--gcc/testsuite/cobol.dg/group2/Numeric_operations__8_.cob37
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_AWAY-FROM-ZERO.cob55
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_AWAY-FROM-ZERO.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.cob55
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-AWAY-FROM-ZERO.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-EVEN.cob55
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-EVEN.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-TOWARD-ZERO.cob55
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_NEAREST-TOWARD-ZERO.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-GREATER.cob55
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-GREATER.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-LESSER.cob55
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_TOWARD-LESSER.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_TRUNCATION.cob55
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDED_TRUNCATION.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.cob427
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_Floating-Point_from_COMPUTE.out71
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.cob428
-rw-r--r--gcc/testsuite/cobol.dg/group2/ROUNDING_omnibus_NumericDisplay_from_COMPUTE.out71
-rw-r--r--gcc/testsuite/cobol.dg/group2/Separate_sign_positions__1_.cob16
-rw-r--r--gcc/testsuite/cobol.dg/group2/Separate_sign_positions__1_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Separate_sign_positions__2_.cob24
-rw-r--r--gcc/testsuite/cobol.dg/group2/Separate_sign_positions__2_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/Simple_TYPEDEF.cob16
-rw-r--r--gcc/testsuite/cobol.dg/group2/Simple_p-scaling.cob33
-rw-r--r--gcc/testsuite/cobol.dg/group2/Simple_p-scaling.out11
-rw-r--r--gcc/testsuite/cobol.dg/group2/debugging_lines__WITH_DEBUGGING_MODE_.cob21
-rw-r--r--gcc/testsuite/cobol.dg/group2/debugging_lines__WITH_DEBUGGING_MODE_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/debugging_lines__not_active_.cob14
-rw-r--r--gcc/testsuite/cobol.dg/group2/debugging_lines__not_active_.out1
-rw-r--r--gcc/testsuite/cobol.dg/group2/integer_arithmetic_on_floating-point_var.cob29
-rw-r--r--gcc/testsuite/g++.dg/abi/macro0.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-noexcept1.C10
-rw-r--r--gcc/testsuite/g++.dg/template/recurse5.C17
-rw-r--r--gcc/testsuite/gcc.dg/pr116479.c26
-rw-r--r--gcc/testsuite/gcc.target/i386/pr119919.c13
-rw-r--r--gcc/testsuite/gcc.target/riscv/arch-25.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-c-1.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-c-2.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-c-3.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-c-4.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-c-5.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-c-6.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-c-7.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-c-8.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-zce-1.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-zce-2.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-zce-3.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-zce-4.c2
-rw-r--r--gcc/testsuite/gcc.target/s390/pr119873-1.c11
-rw-r--r--gcc/testsuite/gcc.target/s390/pr119873-2.c17
-rw-r--r--gcc/testsuite/gcc.target/s390/pr119873-3.c27
-rw-r--r--gcc/testsuite/gcc.target/s390/pr119873-4.c27
-rw-r--r--gcc/testsuite/gcc.target/s390/pr119873-5.c11
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_52.f901
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_57.f9036
-rw-r--r--gcc/tree-ssa-phiopt.cc1
-rw-r--r--libcpp/ChangeLog6
-rw-r--r--libgcc/config/gcn/crt0.c32
-rw-r--r--libgcc/config/nvptx/gbl-ctors.c16
-rw-r--r--libgm2/ChangeLog41
-rw-r--r--libgm2/config.h.in53
-rwxr-xr-xlibgm2/configure371
-rw-r--r--libgm2/configure.ac44
-rw-r--r--libgm2/libm2iso/wraptime.cc60
-rw-r--r--libgomp/ChangeLog50
-rw-r--r--libgomp/Makefile.am2
-rw-r--r--libgomp/Makefile.in7
-rw-r--r--libgomp/config/accel/target-cxa-dso-dtor.c62
-rw-r--r--libgomp/target-cxa-dso-dtor.c3
-rw-r--r--libgomp/testsuite/libgomp.c++/target-cdtor-1.C104
-rw-r--r--libgomp/testsuite/libgomp.c++/target-cdtor-2.C140
-rw-r--r--libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-GCN.C6
-rw-r--r--libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1-offload-sorry-nvptx.C6
-rw-r--r--libgomp/testsuite/libgomp.c++/target-exceptions-pr118794-1.C6
-rw-r--r--libgomp/testsuite/libgomp.c++/target-exceptions-throw-1.C3
-rw-r--r--libgomp/testsuite/libgomp.c++/target-exceptions-throw-2.C3
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/target-cdtor-1.c89
-rw-r--r--libgomp/testsuite/libgomp.c/interop-hsa.c203
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-1.C3
-rw-r--r--libgomp/testsuite/libgomp.oacc-c++/exceptions-throw-2.C3
-rw-r--r--libstdc++-v3/ChangeLog33
-rw-r--r--libstdc++-v3/include/bits/formatfwd.h103
-rw-r--r--libstdc++-v3/include/bits/stl_queue.h14
-rw-r--r--libstdc++-v3/include/bits/stl_stack.h9
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h106
-rw-r--r--libstdc++-v3/include/bits/version.def3
-rw-r--r--libstdc++-v3/include/bits/version.h3
-rw-r--r--libstdc++-v3/include/std/format730
-rw-r--r--libstdc++-v3/include/std/future66
-rw-r--r--libstdc++-v3/include/std/generator10
-rw-r--r--libstdc++-v3/include/std/latch12
-rw-r--r--libstdc++-v3/include/std/queue80
-rw-r--r--libstdc++-v3/include/std/stack48
-rw-r--r--libstdc++-v3/include/std/thread45
-rw-r--r--libstdc++-v3/src/c++23/std.cc.in6
-rw-r--r--libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/48101_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/48101_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/48101_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/48101_neg.cc1
-rw-r--r--libstdc++-v3/testsuite/24_iterators/range_generators/lwg3899.cc57
-rw-r--r--libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc3
-rw-r--r--libstdc++-v3/testsuite/30_threads/packaged_task/cons/lwg4154_neg.cc10
-rw-r--r--libstdc++-v3/testsuite/30_threads/thread/id/output.cc30
-rw-r--r--libstdc++-v3/testsuite/std/format/debug.cc388
-rw-r--r--libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc2
-rw-r--r--libstdc++-v3/testsuite/std/format/parse_ctx.cc2
-rw-r--r--libstdc++-v3/testsuite/std/format/ranges/adaptors.cc156
-rw-r--r--libstdc++-v3/testsuite/std/format/ranges/feature_test.cc9
-rw-r--r--libstdc++-v3/testsuite/std/format/ranges/sequence.cc116
-rw-r--r--libstdc++-v3/testsuite/std/format/ranges/string.cc63
-rw-r--r--libstdc++-v3/testsuite/std/format/string.cc2
-rw-r--r--libstdc++-v3/testsuite/std/format/tuple.cc93
-rwxr-xr-xmaintainer-scripts/gcc_release2
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"