aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog98
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/cobol/genapi.cc704
-rw-r--r--gcc/cobol/genapi.h5
-rw-r--r--gcc/cobol/gengen.cc15
-rw-r--r--gcc/cobol/gengen.h1
-rw-r--r--gcc/cobol/genutil.cc7
-rw-r--r--gcc/cobol/genutil.h4
-rw-r--r--gcc/cobol/symbols.cc2
-rw-r--r--gcc/cobol/symbols.h7
-rw-r--r--gcc/common.opt.urls3
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/fortran/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog58
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_arith.h14
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u128.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u32.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u64.rv32.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u64.rv64.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u128.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u64.rv32.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u64.rv64.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u64-from-u128.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u128.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u16.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u32.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u64.rv32.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u64.rv64.c11
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u128.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u32.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u64.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u32-from-u128.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u32-from-u64.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u64-from-u128.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u128.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u16.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u32.c16
-rw-r--r--gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u64.c16
-rw-r--r--libgcobol/charmaps.cc75
-rw-r--r--libgcobol/charmaps.h30
-rw-r--r--libgcobol/gfileio.cc6
-rw-r--r--libgcobol/libgcobol.cc44
-rw-r--r--libgcobol/valconv.cc3
-rw-r--r--libstdc++-v3/ChangeLog9
-rw-r--r--libstdc++-v3/include/bits/version.def9
-rw-r--r--libstdc++-v3/include/bits/version.h10
-rw-r--r--libstdc++-v3/include/std/utility19
-rw-r--r--libstdc++-v3/src/c++23/std.cc.in3
48 files changed, 996 insertions, 459 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e725926..7d6ac64 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,101 @@
+2025-10-18 Mark Wielaard <mark@klomp.org>
+
+ * common.opt.urls: Regenerate.
+
+2025-10-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/119060
+ * builtins.cc (expand_builtin): Handle BUILT_IN_OBSERVABLE_CHKPT.
+ * builtins.def (BUILT_IN_OBSERVABLE_CHKPT): New.
+ * tree.cc (build_common_builtin_nodes): Build observable
+ checkpoint builtin.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * config/aarch64/aarch64-sve2.md
+ (widen_ssum<mode><Vnarrow>3): Update.
+ (widen_usum<mode><Vnarrow>3): Update.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * config/aarch64/aarch64-sve2.md: (widen_ssum<mode><Vnarrow>3): New.
+ (widen_usum<mode><Vnarrow>3): New.
+ * config/aarch64/iterators.md (Vnarrow): New, to match VNARROW.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * config/aarch64/aarch64-sve.md (widen_<sur>sum<mode><vsi2qi>3): New.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * config/rs6000/altivec.md (widen_usum<mode>3): Rename ...
+ (widen_usumv4si<mode>3): ... to this.
+ (widen_ssumv16qi3): Rename ...
+ (widen_ssumv4siv16qi3): ... to this.
+ (widen_ssumv8hi3): Rename ...
+ (widen_ssumv4siv8hi3): ... to this.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * config/ia64/vect.md (widen_usumv8qi3): Renamed ...
+ (widen_usumv4hiv8qi3): ... into this.
+ (widen_usumv4hi3): Renamed ...
+ (widen_usumv2siv4hi3): ... into this.
+ (widen_ssumv8qi3): Renamed ...
+ (widen_ssumv4hiv8qi3): ... into this.
+ (widen_ssumv4hi3): Renamed ...
+ (widen_ssumv2siv4hi3): ... into this.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * config/arm/iterators.md (v_double_width): New, matching
+ V_double_width.
+ * config/arm/neon.md (widen_ssum<mode>3): Renamed ...
+ (widen_ssum<v_double_width><mode>3, widen_ssum<V_widen_l><mode>3): ...
+ into these.
+ (widen_usum<mode>3): Renamed ...
+ (widen_usum<v_double_width><mode>3, widen_usum<V_widen_l><mode>3): ...
+ into these.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * config/aarch64/aarch64-simd.md (widen_ssum<mode><vsi2qi>3): New.
+ (widen_usum<mode><vsi2qi>3): New.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * config/aarch64/aarch64-simd.md (widen_ssum<mode>3): Change into..
+ (widen_ssum<Vdblw><mode>3, widen_ssum<Vwide><mode>3): ... these.
+ (widen_usum<mode>3): Change into ...
+ (widen_usum<Vdblw><mode>3, widen_usum<Vwide><mode>3): ... these.
+ * config/aarch64/iterators.md (Vdblw): New.
+ (Vwide): Extend to match VWIDE.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * doc/md.texi (widen_ssum@var{n}@var{m}3, widen_usum@var{n}@var{m}3):
+ Update docs.
+ * optabs.cc (expand_widen_pattern_expr): Add WIDEN_SUM_EXPR as widening.
+ * optabs.def (ssum_widen_optab, usum_widen_optab): Convert from direct
+ to a conversion optab.
+ * tree-vect-patterns.cc (vect_recog_widen_sum_pattern): Change
+ vect_supportable_direct_optab_p into vect_supportable_conv_optab_p.
+
+2025-10-18 Linsen Zhou <i@lin.moe>
+
+ PR tree-optimization/122012
+ * tree-object-size.cc (check_for_plus_in_loops): Skip check
+ for the variable offset
+
2025-10-17 David Faust <david.faust@oracle.com>
PR target/122139
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 13c94d5..4ce1a22 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20251018
+20251019
diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index 99dfc07..6fc4770 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -2357,7 +2357,7 @@ static void
move_tree( cbl_field_t *dest,
tree offset,
tree psz_source, // psz_source is a null-terminated string
- tree length_bump=integer_zero_node)
+ tree length_bump=integer_zero_node)
{
// This routine assumes that the psz_source is in the same codeset as the
// dest.
@@ -3774,6 +3774,7 @@ parser_enter_file(const char *filename)
SET_VAR_DECL(var_decl_treeplet_4s , SIZE_T_P , "__gg__treeplet_4s" );
SET_VAR_DECL(var_decl_nop , INT , "__gg__nop" );
SET_VAR_DECL(var_decl_main_called , INT , "__gg__main_called" );
+ SET_VAR_DECL(var_decl_entry_label , VOID_P , "__gg__entry_label" );
}
}
@@ -3865,25 +3866,6 @@ enter_program_common(const char *funcname, const char *funcname_)
current_function->current_section = NULL;
current_function->current_paragraph = NULL;
- // Text conversion must be initialized before the code generated by
- // parser_symbol_add runs.
-
- // The text_conversion_override exists both in the library and in the compiler
-
- __gg__set_internal_codeset(internal_codeset_is_ebcdic());
- gg_call(VOID,
- "__gg__set_internal_codeset",
- internal_codeset_is_ebcdic()
- ? integer_one_node : integer_zero_node,
- NULL_TREE);
-
- __gg__text_conversion_override(td_default_e, cs_default_e);
- gg_call(VOID,
- "__gg__text_conversion_override",
- build_int_cst_type(INT, td_default_e),
- build_int_cst_type(INT, cs_default_e),
- NULL_TREE);
-
gg_call(VOID,
"__gg__codeset_figurative_constants",
NULL_TREE);
@@ -5059,29 +5041,34 @@ parser_alphabet( cbl_alphabet_t& alphabet )
SHOW_PARSE
{
SHOW_PARSE_HEADER
- fprintf(stderr, "%s\n", alphabet.name);
+ char *psz = xasprintf(" %s ", alphabet.name);
+ SHOW_PARSE_TEXT(psz);
+ free(psz);
switch(alphabet.encoding)
{
case ASCII_e:
- fprintf(stderr, "ASCII\n");
+ psz = xasprintf("ASCII");
break;
case iso646_e:
- fprintf(stderr, "ISO646\n");
+ psz = xasprintf("ISO646");
break;
case EBCDIC_e:
- fprintf(stderr, "EBCDIC\n");
+ psz = xasprintf("EBCDIC");
break;
case UTF8_e:
- fprintf(stderr, "UTF8\n");
+ psz = xasprintf("UTF8");
break;
case custom_encoding_e:
- fprintf(stderr, "%s\n", alphabet.name);
+ psz = xasprintf("%s", alphabet.name);
break;
default:
{ const char * p = __gg__encoding_iconv_name( alphabet.encoding );
- fprintf(stderr, "%s\n", p? p : "[unknown]");
+ psz = xasprintf("%s", p? p : "[unknown]");
}
}
+ SHOW_PARSE_TEXT(" ");
+ SHOW_PARSE_TEXT(psz);
+ free(psz);
SHOW_PARSE_END
}
@@ -5122,6 +5109,7 @@ parser_alphabet( cbl_alphabet_t& alphabet )
gg_get_address_of(table256),
build_int_cst_type(INT, alphabet.low_index),
build_int_cst_type(INT, alphabet.high_index),
+
NULL_TREE );
break;
}
@@ -5137,26 +5125,31 @@ parser_alphabet_use( cbl_alphabet_t& alphabet )
SHOW_PARSE
{
SHOW_PARSE_HEADER
+ char *psz = xasprintf(" %s ", alphabet.name);
+ SHOW_PARSE_TEXT(psz);
+ free(psz);
switch(alphabet.encoding)
{
case ASCII_e:
- fprintf(stderr, "ASCII\n");
+ psz = xasprintf("ASCII");
break;
case iso646_e:
- fprintf(stderr, "ISO646\n");
+ psz = xasprintf("ISO646");
break;
case EBCDIC_e:
- fprintf(stderr, "EBCDIC\n");
+ psz = xasprintf("EBCDIC");
break;
case UTF8_e:
- fprintf(stderr, "UTF8\n");
+ psz = xasprintf("UTF8");
break;
case custom_encoding_e:
- fprintf(stderr, "%s\n", alphabet.name);
+ psz = xasprintf("%s", alphabet.name);
break;
default:
gcc_unreachable();
}
+ SHOW_PARSE_TEXT(psz);
+ free(psz);
SHOW_PARSE_END
}
@@ -5174,6 +5167,7 @@ parser_alphabet_use( cbl_alphabet_t& alphabet )
__gg__high_value_character = DEGENERATE_HIGH_VALUE;
gg_call(VOID,
"__gg__alphabet_use",
+ build_int_cst_type(INT, current_encoding(encoding_display_e)),
build_int_cst_type(INT, alphabet.encoding),
null_pointer_node,
NULL_TREE);
@@ -5189,6 +5183,7 @@ parser_alphabet_use( cbl_alphabet_t& alphabet )
gg_call(VOID,
"__gg__alphabet_use",
+ build_int_cst_type(INT, current_encoding(encoding_display_e)),
build_int_cst_type(INT, alphabet.encoding),
build_int_cst_type(SIZE_T, alphabet_index),
NULL_TREE);
@@ -6938,6 +6933,7 @@ initialize_the_data()
// This is one-time initialization of the libgcobol program state stack
gg_call(VOID,
"__gg__init_program_state",
+ build_int_cst_type(INT, current_encoding(encoding_display_e)),
NULL_TREE);
__gg__currency_signs = __gg__ct_currency_signs;
@@ -6989,6 +6985,280 @@ initialize_the_data()
}
}
+static
+void
+establish_using(size_t nusing,
+ cbl_ffi_arg_t args[] )
+ {
+ if( nusing )
+ {
+ for(size_t i=0; i<nusing; i++)
+ {
+ // This code is relevant at compile time. It takes each
+ // expected formal parameter and tacks it onto the end of the
+ // function's arguments chain.
+
+ char *ach = xasprintf("_p_%s", args[i].refer.field->name);
+
+ size_t nbytes = 0;
+ tree par_type = tree_type_from_field_type(args[i].refer.field, nbytes);
+ if( par_type == FLOAT )
+ {
+ par_type = SSIZE_T;
+ }
+ if( par_type == DOUBLE )
+ {
+ par_type = SSIZE_T;
+ }
+ if( par_type == FLOAT128 )
+ {
+ par_type = INT128;
+ }
+ chain_parameter_to_function(current_function->function_decl, par_type, ach);
+ free(ach);
+ }
+
+ // During the call, we saved the parameter_count and an array of variable
+ // lengths. We need to look at those values if, and only if, one or more
+ // of our USING arguments has an OPTIONAL flag or if one of our targets is
+ // marked as VARYING.
+ bool check_for_parameter_count = false;
+ for(size_t i=0; i<nusing; i++)
+ {
+ if( args[i].optional )
+ {
+ check_for_parameter_count = true;
+ break;
+ }
+ if( args[i].refer.field->attr & any_length_e )
+ {
+ check_for_parameter_count = true;
+ break;
+ }
+ }
+
+ if( check_for_parameter_count )
+ {
+ IF( var_decl_call_parameter_signature,
+ eq_op,
+ gg_cast(CHAR_P, current_function->function_address) )
+ {
+ // We know to use var_decl_call_parameter_count, so unflag this
+ // pointer to avoid problems in the ridiculous possibility of
+ // COBOL-A calls C_B calls COBOL_A
+ gg_assign(var_decl_call_parameter_signature,
+ gg_cast(CHAR_P, null_pointer_node));
+ }
+ ELSE
+ {
+ // We were apparently called by a C routine, not a COBOL routine, so
+ // make sure we don't get shortchanged by a count left behind from an
+ // earlier COBOL call.
+ gg_assign(var_decl_call_parameter_count,
+ build_int_cst_type(INT, A_ZILLION));
+ }
+ ENDIF
+ }
+ else
+ {
+ // None of our parameters require a count, so make sure we don't get
+ // bamboozled by a count left behind from an earlier COBOL call.
+ gg_assign(var_decl_call_parameter_count,
+ build_int_cst_type(INT, A_ZILLION));
+ }
+
+ // There are 'nusing' elements in the PROCEDURE DIVISION USING list.
+
+ tree parameter = NULL_TREE;
+ tree rt_i = gg_define_int();
+ for(size_t i=0; i<nusing; i++)
+ {
+ // And this compiler code generates run-time execution code. The
+ // generated code picks up, at run time, the variable we just
+ // established in the chain at compile time.
+
+ // It makes more sense if you don't think about it too hard.
+
+ // We need to be able to restore prior arguments when doing recursive
+ // calls:
+ IF( member(args[i].refer.field->var_decl_node, "data"),
+ ne_op,
+ gg_cast(UCHAR_P, null_pointer_node) )
+ {
+ gg_call(VOID,
+ "__gg__push_local_variable",
+ gg_get_address_of(args[i].refer.field->var_decl_node),
+ NULL_TREE);
+ }
+ ELSE
+ ENDIF
+
+ tree base = gg_define_variable(UCHAR_P);
+ gg_assign(rt_i, build_int_cst_type(INT, i));
+ //gg_printf("The rt_i counter is %d\n", rt_i, NULL_TREE);
+ IF( rt_i, lt_op , var_decl_call_parameter_count )
+ {
+ if( i == 0 )
+ {
+ // This is the first parameter.
+ parameter = DECL_ARGUMENTS(current_function->function_decl);
+ }
+ else
+ {
+ // These are subsequent parameters
+ parameter = TREE_CHAIN(parameter);
+ }
+ gg_assign(base, gg_cast(UCHAR_P, parameter));
+
+ if( args[i].refer.field->attr & any_length_e )
+ {
+ // gg_printf("side channel: Length of \"%s\" is %ld\n",
+ // member(args[i].refer.field->var_decl_node, "name"),
+ // gg_array_value(var_decl_call_parameter_lengths, rt_i),
+ // NULL_TREE);
+
+ // Get the length from the global lengths[] side channel. Don't
+ // forget to use the length mask on the table value.
+ gg_assign(member(args[i].refer.field->var_decl_node, "capacity"),
+ gg_array_value(var_decl_call_parameter_lengths, rt_i));
+ }
+ }
+ ELSE
+ {
+ gg_assign(base, gg_cast(UCHAR_P, null_pointer_node));
+ }
+ ENDIF
+
+ // Arriving here means that we are processing an instruction like
+ // this:
+ // PROCEDURE DIVISION USING using[0] using[1] ... using using[nusing-1]
+
+ // When __gg__call_parameter_count is equal to A_ZILLION, then this is
+ // an OTHER-TO-COBOL call and the var_decl_call_parameter_lengths array
+ // is not valid
+
+ cbl_ffi_crv_t crv = args[i].crv;
+ cbl_field_t *new_var = args[i].refer.field;
+
+ if( crv == by_value_e )
+ {
+ switch(new_var->type)
+ {
+ case FldGroup:
+ case FldAlphanumeric:
+ case FldAlphaEdited:
+ case FldNumericEdited:
+ crv = by_reference_e;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if( crv == by_value_e )
+ {
+ // 'parameter' is the 64-bit or 128-bit value that was placed on the stack
+
+ size_t nbytes;
+ tree_type_from_field_type(new_var, nbytes);
+ tree parm = gg_define_variable(INT128);
+
+ if( nbytes <= 8 )
+ {
+ // Our input is a 64-bit number
+ if( new_var->attr & signable_e )
+ {
+ IF( gg_bitwise_and( gg_cast(SIZE_T, base),
+ build_int_cst_type(SIZE_T, 0x8000000000000000ULL)),
+ ne_op,
+ gg_cast(SIZE_T, integer_zero_node) )
+ {
+ // Our input is a negative number
+ gg_assign(parm, gg_cast(INT128, integer_minus_one_node));
+ }
+ ELSE
+ {
+ // Our input is a positive number
+ gg_assign(parm, gg_cast(INT128, integer_zero_node));
+ }
+ ENDIF
+ }
+ else
+ {
+ // This is a 64-bit positive number:
+ gg_assign(parm, gg_cast(INT128, integer_zero_node));
+ }
+ }
+ // At this point, parm has been set to 0 or -1
+
+ gg_memcpy(gg_get_address_of(parm),
+ gg_get_address_of(base),
+ build_int_cst_type(SIZE_T, nbytes));
+
+ tree array_type = build_array_type_nelts(UCHAR, new_var->data.capacity);
+ tree data_decl_node = gg_define_variable( array_type,
+ NULL,
+ vs_static);
+ gg_assign( member(new_var->var_decl_node, "data"),
+ gg_get_address_of(data_decl_node) );
+
+ // And then move it into place
+ gg_call(VOID,
+ "__gg__assign_value_from_stack",
+ gg_get_address_of(new_var->var_decl_node),
+ parm,
+ NULL_TREE);
+ // We now have to handle an oddball situation. It's possible we are
+ // dealing with
+ //
+ // linkage section.
+ // 01 var1
+ // 01 var2 redefines var1
+ //
+ // If so, we have to give var2::data_pointer the same value as
+ // var1::data_pointer
+ //
+ size_t our_index = symbol_index(symbol_elem_of(new_var));
+ size_t next_index = our_index + 1;
+ // Look ahead in the symbol table for the next LEVEL01/77
+ for(;;)
+ {
+ symbol_elem_t *e = symbol_at(next_index);
+ if( e->type != SymField )
+ {
+ break;
+ }
+ cbl_field_t *next_var = cbl_field_of(e);
+ if( !next_var )
+ {
+ break;
+ }
+ if( next_var->level == LEVEL01 || next_var->level == LEVEL77 )
+ {
+ if( next_var->parent == our_index )
+ {
+ gg_assign(member(next_var->var_decl_node, "data"),
+ member(new_var->var_decl_node, "data"));
+ }
+ break;
+ }
+ next_index += 1;
+ }
+ }
+ else
+ {
+ // 'parameter' is a reference, so it it becomes the data member of
+ // the cblc_field_t COBOL variable.
+ gg_assign(member(args[i].field()->var_decl_node, "data"), base);
+
+ // We need to apply base + offset to the LINKAGE variable
+ // and all of its children
+ propogate_linkage_offsets( args[i].field(), base );
+ }
+ }
+ }
+ }
+
void
parser_division(cbl_division_t division,
cbl_field_t *returning,
@@ -7187,273 +7457,6 @@ parser_division(cbl_division_t division,
// length. We establish those lengths based on the types of the target
// for each USING.
- for(size_t i=0; i<nusing; i++)
- {
- // This code is relevant at compile time. It takes each
- // expected formal parameter and tacks it onto the end of the
- // function's arguments chain.
-
- sprintf(ach, "_p_%s", args[i].refer.field->name);
-
- size_t nbytes = 0;
- tree par_type = tree_type_from_field_type(args[i].refer.field, nbytes);
- if( par_type == FLOAT )
- {
- par_type = SSIZE_T;
- }
- if( par_type == DOUBLE )
- {
- par_type = SSIZE_T;
- }
- if( par_type == FLOAT128 )
- {
- par_type = INT128;
- }
- chain_parameter_to_function(current_function->function_decl, par_type, ach);
- }
-
- if( nusing )
- {
- // During the call, we saved the parameter_count and an array of variable
- // lengths. We need to look at those values if, and only if, one or more
- // of our USING arguments has an OPTIONAL flag or if one of our targets is
- // marked as VARYING.
- bool check_for_parameter_count = false;
- for(size_t i=0; i<nusing; i++)
- {
- if( args[i].optional )
- {
- check_for_parameter_count = true;
- break;
- }
- if( args[i].refer.field->attr & any_length_e )
- {
- check_for_parameter_count = true;
- break;
- }
- }
-
- if( check_for_parameter_count )
- {
- IF( var_decl_call_parameter_signature,
- eq_op,
- gg_cast(CHAR_P, current_function->function_address) )
- {
- // We know to use var_decl_call_parameter_count, so unflag this
- // pointer to avoid problems in the ridiculous possibility of
- // COBOL-A calls C_B calls COBOL_A
- gg_assign(var_decl_call_parameter_signature,
- gg_cast(CHAR_P, null_pointer_node));
- }
- ELSE
- {
- // We were apparently called by a C routine, not a COBOL routine, so
- // make sure we don't get shortchanged by a count left behind from an
- // earlier COBOL call.
- gg_assign(var_decl_call_parameter_count,
- build_int_cst_type(INT, A_ZILLION));
- }
- ENDIF
- }
- else
- {
- // None of our parameters require a count, so make sure we don't get
- // bamboozled by a count left behind from an earlier COBOL call.
- gg_assign(var_decl_call_parameter_count,
- build_int_cst_type(INT, A_ZILLION));
- }
-
- // There are 'nusing' elements in the PROCEDURE DIVISION USING list.
-
- tree parameter = NULL_TREE;
- tree rt_i = gg_define_int();
- for(size_t i=0; i<nusing; i++)
- {
- // And this compiler code generates run-time execution code. The
- // generated code picks up, at run time, the variable we just
- // established in the chain at compile time.
-
- // It makes more sense if you don't think about it too hard.
-
- // We need to be able to restore prior arguments when doing recursive
- // calls:
- IF( member(args[i].refer.field->var_decl_node, "data"),
- ne_op,
- gg_cast(UCHAR_P, null_pointer_node) )
- {
- gg_call(VOID,
- "__gg__push_local_variable",
- gg_get_address_of(args[i].refer.field->var_decl_node),
- NULL_TREE);
- }
- ELSE
- ENDIF
-
- tree base = gg_define_variable(UCHAR_P);
- gg_assign(rt_i, build_int_cst_type(INT, i));
- //gg_printf("The rt_i counter is %d\n", rt_i, NULL_TREE);
- IF( rt_i, lt_op , var_decl_call_parameter_count )
- {
- if( i == 0 )
- {
- // This is the first parameter.
- parameter = DECL_ARGUMENTS(current_function->function_decl);
- }
- else
- {
- // These are subsequent parameters
- parameter = TREE_CHAIN(parameter);
- }
- gg_assign(base, gg_cast(UCHAR_P, parameter));
-
- if( args[i].refer.field->attr & any_length_e )
- {
- // gg_printf("side channel: Length of \"%s\" is %ld\n",
- // member(args[i].refer.field->var_decl_node, "name"),
- // gg_array_value(var_decl_call_parameter_lengths, rt_i),
- // NULL_TREE);
-
- // Get the length from the global lengths[] side channel. Don't
- // forget to use the length mask on the table value.
- gg_assign(member(args[i].refer.field->var_decl_node, "capacity"),
- gg_array_value(var_decl_call_parameter_lengths, rt_i));
- }
- }
- ELSE
- {
- gg_assign(base, gg_cast(UCHAR_P, null_pointer_node));
- }
- ENDIF
-
- // Arriving here means that we are processing an instruction like
- // this:
- // PROCEDURE DIVISION USING using[0] using[1] ... using using[nusing-1]
-
- // When __gg__call_parameter_count is equal to A_ZILLION, then this is
- // an OTHER-TO-COBOL call and the var_decl_call_parameter_lengths array
- // is not valid
-
- cbl_ffi_crv_t crv = args[i].crv;
- cbl_field_t *new_var = args[i].refer.field;
-
- if( crv == by_value_e )
- {
- switch(new_var->type)
- {
- case FldGroup:
- case FldAlphanumeric:
- case FldAlphaEdited:
- case FldNumericEdited:
- crv = by_reference_e;
- break;
- default:
- break;
- }
- }
-
- if( crv == by_value_e )
- {
- // 'parameter' is the 64-bit or 128-bit value that was placed on the stack
-
- size_t nbytes;
- tree_type_from_field_type(new_var, nbytes);
- tree parm = gg_define_variable(INT128);
-
- if( nbytes <= 8 )
- {
- // Our input is a 64-bit number
- if( new_var->attr & signable_e )
- {
- IF( gg_bitwise_and( gg_cast(SIZE_T, base),
- build_int_cst_type(SIZE_T, 0x8000000000000000ULL)),
- ne_op,
- gg_cast(SIZE_T, integer_zero_node) )
- {
- // Our input is a negative number
- gg_assign(parm, gg_cast(INT128, integer_minus_one_node));
- }
- ELSE
- {
- // Our input is a positive number
- gg_assign(parm, gg_cast(INT128, integer_zero_node));
- }
- ENDIF
- }
- else
- {
- // This is a 64-bit positive number:
- gg_assign(parm, gg_cast(INT128, integer_zero_node));
- }
- }
- // At this point, parm has been set to 0 or -1
-
- gg_memcpy(gg_get_address_of(parm),
- gg_get_address_of(base),
- build_int_cst_type(SIZE_T, nbytes));
-
- tree array_type = build_array_type_nelts(UCHAR, new_var->data.capacity);
- tree data_decl_node = gg_define_variable( array_type,
- NULL,
- vs_static);
- gg_assign( member(new_var->var_decl_node, "data"),
- gg_get_address_of(data_decl_node) );
-
- // And then move it into place
- gg_call(VOID,
- "__gg__assign_value_from_stack",
- gg_get_address_of(new_var->var_decl_node),
- parm,
- NULL_TREE);
- // We now have to handle an oddball situation. It's possible we are
- // dealing with
- //
- // linkage section.
- // 01 var1
- // 01 var2 redefines var1
- //
- // If so, we have to give var2::data_pointer the same value as
- // var1::data_pointer
- //
- size_t our_index = symbol_index(symbol_elem_of(new_var));
- size_t next_index = our_index + 1;
- // Look ahead in the symbol table for the next LEVEL01/77
- for(;;)
- {
- symbol_elem_t *e = symbol_at(next_index);
- if( e->type != SymField )
- {
- break;
- }
- cbl_field_t *next_var = cbl_field_of(e);
- if( !next_var )
- {
- break;
- }
- if( next_var->level == LEVEL01 || next_var->level == LEVEL77 )
- {
- if( next_var->parent == our_index )
- {
- gg_assign(member(next_var->var_decl_node, "data"),
- member(new_var->var_decl_node, "data"));
- }
- break;
- }
- next_index += 1;
- }
- }
- else
- {
- // 'parameter' is a reference, so it it becomes the data member of
- // the cblc_field_t COBOL variable.
- gg_assign(member(args[i].field()->var_decl_node, "data"), base);
-
- // We need to apply base + offset to the LINKAGE variable
- // and all of its children
- propogate_linkage_offsets( args[i].field(), base );
- }
- }
- }
-
gg_call(VOID,
"__gg__pseudo_return_bookmark",
NULL_TREE);
@@ -7504,6 +7507,25 @@ parser_division(cbl_division_t division,
// logic for backing up one line, which is needed to correctly step through
// COBOL code with GDB-COBOL. So, we clear it here.
current_location_minus_one_clear();
+
+ // It is at this point that we check to see if the call to this function
+ // is a re-entry because of an ENTRY statement:
+
+ IF( var_decl_entry_label, ne_op, null_pointer_node )
+ {
+ // This is an ENTRY re-entry. The processing of USING variables was
+ // done in parser_entry, so now we jump to the label
+ static tree loc = gg_define_variable(VOID_P, vs_static);
+ gg_assign(loc, var_decl_entry_label);
+ gg_assign(var_decl_entry_label, gg_cast(VOID_P, null_pointer_node));
+ gg_goto(loc);
+ }
+ ELSE
+ {
+ }
+ ENDIF
+
+ establish_using(nusing, args);
}
}
@@ -9683,7 +9705,10 @@ parser_file_add(struct cbl_file_t *file)
build_int_cst_type(INT, (int)file->optional),
build_int_cst_type(SIZE_T, varies.min),
build_int_cst_type(SIZE_T, varies.max),
- build_int_cst_type(INT, (int)file->codeset.encoding),
+/* Right now, file->codeset.encoding is not being set properly. Remove this
+ comment and fix the following code when that's repaired. */
+// build_int_cst_type(INT, (int)file->codeset.encoding),
+ build_int_cst_type(INT, current_encoding(encoding_display_e)),
build_int_cst_type(INT, (int)file->codeset.alphabet),
NULL_TREE);
file->var_decl_node = new_var_decl;
@@ -9776,7 +9801,7 @@ parser_file_open( struct cbl_file_t *file, int mode_char )
gg_call( CHAR_P,
"__gg__convert_encoding",
psz,
- build_int_cst_type(INT,
+ build_int_cst_type(INT,
field_of_name->codeset.encoding),
build_int_cst_type(INT,
DEFAULT_CHARMAP_SOURCE),
@@ -13274,7 +13299,9 @@ create_and_call(size_t narg,
{
// Because no explicit returning value is expected, we just call it. We
// expect COBOL routines to set RETURN-CODE when they think it necessary.
+ push_program_state();
gg_append_statement(call_expr);
+ pop_program_state();
}
for( size_t i=0; i<narg; i++ )
@@ -13482,10 +13509,79 @@ parser_entry_activate( size_t iprog, const cbl_label_t *declarative )
assert(iprog == symbol_elem_of(declarative)->program);
}
-// Define ENTRY point with alternative LINKAGE
+static tree entry_goto;
+static tree entry_label;
+static tree entry_addr;
+
void
-parser_entry( cbl_field_t */*name*/, size_t /*narg*/, cbl_ffi_arg_t */*args*/ )
+parser_entry( const cbl_field_t *name, size_t nusing, cbl_ffi_arg_t *args )
{
+ // We are implementing the ENTRY statement, which creates an alternative
+ // entry point into the current program-id. There is no actual way to do
+ // that literally. So, we are going to create a separate routine that sets
+ // things up and then calls the current routine with the information it needs
+ // to transfer processing to the ENTRY point.
+
+ SHOW_PARSE
+ {
+ SHOW_PARSE_HEADER
+ SHOW_PARSE_FIELD( " ENTRY ", name)
+ SHOW_PARSE_END
+ }
+
+ // Get the name of the program that contains the ENTRY statement.
+ char *name_of_parent = xstrdup(current_function->our_name);
+
+ // Get the name of the ENTRY point.
+ // cppcheck-suppress nullPointerRedundantCheck
+ char *psz = cobol_name_mangler(name->data.initial);
+
+ // Create a goto/label pair. The label will be set up here; the goto will
+ // be used when we re-enter the containing function:
+
+ gg_create_goto_pair(&entry_goto,
+ &entry_label,
+ &entry_addr);
+
+ // Start creating the ENTRY function.
+ tree function_decl = gg_define_function( VOID,
+ psz,
+ psz,
+ NULL_TREE);
+ free(psz);
+
+ // Modify the default settings for this entry point
+ TREE_ADDRESSABLE(function_decl) = 0;
+ TREE_USED(function_decl) = 0;
+ TREE_NOTHROW(function_decl) = 0;
+ TREE_STATIC(function_decl) = 1;
+ DECL_EXTERNAL (function_decl) = 0;
+ TREE_PUBLIC (function_decl) = 1;
+ DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(function_decl) = 1;
+
+ // When the ENTRY function point is called, we process its "using"
+ // parameters:
+ establish_using(nusing, args);
+
+ // Put the entry_label into the global variable that will be picked up
+ // when the containing program-id is re-entered:
+ gg_assign(var_decl_entry_label, entry_addr);
+
+ // Get the function address of the containing function.
+ tree gfa = gg_get_function_address(VOID, name_of_parent);
+ free(name_of_parent);
+
+ // Call the containing function
+ gg_append_statement(gg_call_expr_list(VOID,
+ gfa,
+ 0,
+ NULL));
+ // We are done with the ENTRY function:
+ gg_finalize_function();
+
+ // Lay down the address of the label that matches var_decl_entry_label;
+ // the containing program-id will jump to this point.
+ gg_append_statement(entry_label);
}
void
@@ -14522,7 +14618,7 @@ mh_source_is_literalN(cbl_refer_t &destref,
// __gg__string_to_alpha_edited expects the source string to be in
// the same encoding as the target:
size_t len = strlen(sourceref.field->data.initial);
- char *src =
+ char *src =
static_cast<char *>(xmalloc(len+1));
memcpy( src,
sourceref.field->data.initial,
diff --git a/gcc/cobol/genapi.h b/gcc/cobol/genapi.h
index b86be8e..1aafc65 100644
--- a/gcc/cobol/genapi.h
+++ b/gcc/cobol/genapi.h
@@ -558,8 +558,9 @@ void parser_call( cbl_refer_t name,
void parser_entry_activate( size_t iprog, const cbl_label_t *declarative );
-void parser_entry( cbl_field_t *name,
- size_t narg = 0, cbl_ffi_arg_t args[] = NULL);
+void parser_entry( const cbl_field_t *name,
+ size_t narg = 0,
+ cbl_ffi_arg_t args[] = NULL);
bool is_ascending_key(const cbl_refer_t& key);
diff --git a/gcc/cobol/gengen.cc b/gcc/cobol/gengen.cc
index 3ad3344..f3642f2 100644
--- a/gcc/cobol/gengen.cc
+++ b/gcc/cobol/gengen.cc
@@ -1830,7 +1830,10 @@ gg_build_logical_expression(tree operand_a,
}
void
-gg_create_goto_pair(tree *goto_expr, tree *label_expr, tree *label_addr, const char *name)
+gg_create_goto_pair(tree *goto_expr,
+ tree *label_expr,
+ tree *label_addr,
+ const char *name)
{
// We are going to create a pair of expressions for our
// caller. They are a matched set of goto/label expressions,
@@ -1887,16 +1890,6 @@ gg_create_goto_pair(tree *goto_expr,
}
void
-gg_goto_label_decl(tree label_decl)
- {
- tree goto_expr = build1_loc( gg_token_location(),
- GOTO_EXPR,
- void_type_node,
- label_decl);
- gg_append_statement(goto_expr);
- }
-
-void
gg_create_goto_pair(tree *goto_expr, tree *label_expr)
{
// We are going to create a pair of expressions for our
diff --git a/gcc/cobol/gengen.h b/gcc/cobol/gengen.h
index 96e69dd..e785ac7 100644
--- a/gcc/cobol/gengen.h
+++ b/gcc/cobol/gengen.h
@@ -495,7 +495,6 @@ void gg_create_goto_pair( tree *goto_expr,
tree *label_expr,
tree *label_addr,
tree *label_decl);
-void gg_goto_label_decl(tree label_decl);
// Used for implementing SECTIONS and PARAGRAPHS. When you have a
// void *pointer = &&label, gg_goto is the same as
diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc
index 33057ff..56b6b83 100644
--- a/gcc/cobol/genutil.cc
+++ b/gcc/cobol/genutil.cc
@@ -50,8 +50,6 @@
#include "../../libgcobol/exceptl.h"
#include "exceptg.h"
-bool internal_codeset_is_ebcdic() { return gcobol_feature_internal_ebcdic(); }
-
bool exception_location_active = true;
bool skip_exception_processing = true;
@@ -107,8 +105,13 @@ tree var_decl_treeplet_4s; // SIZE_T_P , "__gg__treeplet_4s"
// wasn't successful figuring out how to create an actual NOP assembly language
// instruction, I instead gg_assign(var_decl_nop, integer_zero_node)
tree var_decl_nop; // int __gg__nop;
+
+// Indicates which routine main() called
tree var_decl_main_called; // int __gg__main_called;
+// Indicates the target label for an ENTRY statement
+tree var_decl_entry_label; // void* __gg__entry_label
+
#if 0
#define REFER(a)
#else
diff --git a/gcc/cobol/genutil.h b/gcc/cobol/genutil.h
index e53e11a..251b1c1 100644
--- a/gcc/cobol/genutil.h
+++ b/gcc/cobol/genutil.h
@@ -30,8 +30,6 @@
#ifndef _GENUTIL_H_
#define _GENUTIL_H_
-bool internal_codeset_is_ebcdic();
-
extern bool exception_location_active;
extern bool skip_exception_processing;
@@ -79,9 +77,9 @@ extern tree var_decl_treeplet_3s; // SIZE_T_P , "__gg__treeplet_3
extern tree var_decl_treeplet_4f; // cblc_field_pp_type_node , "__gg__treeplet_4f"
extern tree var_decl_treeplet_4o; // SIZE_T_P , "__gg__treeplet_4o"
extern tree var_decl_treeplet_4s; // SIZE_T_P , "__gg__treeplet_4s"
-
extern tree var_decl_nop; // int __gg__nop
extern tree var_decl_main_called; // int __gg__main_called
+extern tree var_decl_entry_label; // void* __gg__entry_label
int get_scaled_rdigits(cbl_field_t *field);
int get_scaled_digits(cbl_field_t *field);
diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc
index d575119..b6f4a37 100644
--- a/gcc/cobol/symbols.cc
+++ b/gcc/cobol/symbols.cc
@@ -1643,7 +1643,7 @@ symbols_alphabet_set( size_t program, const char name[]) {
};
// Define alphabets for codegen.
- std::for_each(symbols_begin(), symbols_end(), alpha() );
+ std::for_each(symbols_begin(program), symbols_end(), alpha() );
// Set collation sequence before parser_symbol_add.
if( name ) {
diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h
index ea607db..b24283a 100644
--- a/gcc/cobol/symbols.h
+++ b/gcc/cobol/symbols.h
@@ -503,6 +503,13 @@ const char * __gg__encoding_iconv_name( cbl_encoding_t encoding );
bool is_elementary( enum cbl_field_type_t type );
+// These were introduced to discourage the use of
+// current_encoding('A') and current_encoding('N')
+enum
+ {
+ encoding_display_e = 'A',
+ encoding_national_e = 'N'
+ };
cbl_encoding_t current_encoding( char a_or_n );
/* In cbl_field_t:
diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls
index ab6b431..828db53 100644
--- a/gcc/common.opt.urls
+++ b/gcc/common.opt.urls
@@ -1550,6 +1550,9 @@ UrlSuffix(gcc/Optimize-Options.html#index-ftree-loop-optimize)
ftree-parallelize-loops=
UrlSuffix(gcc/Optimize-Options.html#index-ftree-parallelize-loops)
+ftree-parallelize-loops
+UrlSuffix(gcc/Optimize-Options.html#index-ftree-parallelize-loops)
+
ftree-phiprop
UrlSuffix(gcc/Optimize-Options.html#index-ftree-phiprop)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ecf3986..3bf1e7d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+2025-10-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/119060
+ * cxxapi-data.csv: Add observable_checkpoint to <utility>.
+ * std-name-hint.gperf: Add observable_checkpoint to <utility>.
+ * std-name-hint.h: Regenerate.
+
+2025-10-18 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/122279
+ * module.cc (depset::hash::add_namespace_entities): Seed any
+ purview using-decls.
+ (module_state::write_using_directives): Stream if the udir was
+ exported or not.
+ (module_state::read_using_directives): Add the using-directive
+ if it's either exported or part of this module.
+
2025-10-14 Patrick Palka <ppalka@redhat.com>
PR c++/122192
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c5eb7f2..81d666c 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,10 @@
+2025-10-18 Yuao Ma <c8ef@outlook.com>
+
+ * resolve.cc (resolve_conditional): Allow character in cond-expr.
+ * trans-const.cc (gfc_conv_constant): Handle want_pointer.
+ * trans-expr.cc (gfc_conv_conditional_expr): Fill se->string_length.
+ (gfc_conv_string_parameter): Handle COND_EXPR tree code.
+
2025-10-17 Josef Melcr <jmelcr02@gmail.com>
* f95-lang.cc (ATTR_CALLBACK_GOMP_LIST): New attr list
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2c250a1..971f67f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,61 @@
+2025-10-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/119060
+ * g++.dg/cpp26/observable-checkpoint.C: New test.
+
+2025-10-18 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/122279
+ * g++.dg/modules/namespace-13_b.C: Adjust expected results.
+ * g++.dg/modules/namespace-13_c.C: Test non-exported
+ using-directive is not used.
+ * g++.dg/modules/namespace-14_a.C: New test.
+ * g++.dg/modules/namespace-14_b.C: New test.
+ * g++.dg/modules/namespace-14_c.C: New test.
+ * g++.dg/modules/namespace-14_d.C: New test.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * gcc.target/aarch64/sve2/pr122069_3.c: New test.
+ * gcc.target/aarch64/sve2/pr122069_4.c: New test.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * gcc.target/aarch64/sve2/pr122069_1.c: New test.
+ * gcc.target/aarch64/sve2/pr122069_2.c: New test.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * gcc.target/aarch64/sve/pr122069_1.c: New test.
+ * gcc.target/aarch64/sve/pr122069_2.c: New test.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * gcc.target/aarch64/pr122069_3.c: New test.
+ * gcc.target/aarch64/pr122069_4.c: New test.
+
+2025-10-18 Tamar Christina <tamar.christina@arm.com>
+
+ PR middle-end/122069
+ * gcc.target/aarch64/pr122069_1.c: New test.
+ * gcc.target/aarch64/pr122069_2.c: New test.
+
+2025-10-18 Yuao Ma <c8ef@outlook.com>
+
+ * gfortran.dg/conditional_1.f90: Test character type.
+ * gfortran.dg/conditional_2.f90: Test print constants.
+ * gfortran.dg/conditional_4.f90: Test diagnostic message.
+ * gfortran.dg/conditional_6.f90: Test character cond-arg.
+
+2025-10-18 Linsen Zhou <i@lin.moe>
+
+ PR tree-optimization/122012
+ * gcc.dg/torture/pr122012.c: New test.
+
2025-10-17 David Faust <david.faust@oracle.com>
PR target/122139
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h b/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h
index 7cd16a2..e1748a6 100644
--- a/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_arith.h
@@ -756,4 +756,18 @@ sat_u_mul_##NT##_from_##WT##_fmt_5 (NT a, NT b) \
sat_u_mul_##NT##_from_##WT##_fmt_5 (a, b)
#define RUN_SAT_U_MUL_FMT_5_WRAP(NT, WT, a, b) RUN_SAT_U_MUL_FMT_5(NT, WT, a, b)
+#define DEF_SAT_U_MUL_FMT_6(NT, WT) \
+NT __attribute__((noinline)) \
+sat_u_mul_##NT##_from_##WT##_fmt_6 (NT a, NT b) \
+{ \
+ WT x = (WT)a * (WT)b; \
+ NT max = -1; \
+ return x > (WT)(max) ? max : (NT)x; \
+}
+
+#define DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT) DEF_SAT_U_MUL_FMT_6(NT, WT)
+#define RUN_SAT_U_MUL_FMT_6(NT, WT, a, b) \
+ sat_u_mul_##NT##_from_##WT##_fmt_6 (a, b)
+#define RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, a, b) RUN_SAT_U_MUL_FMT_6(NT, WT, a, b)
+
#endif
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u128.c
new file mode 100644
index 0000000..990b820
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u128.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint16_t
+#define WT uint128_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u32.c
new file mode 100644
index 0000000..dadf28a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u32.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint16_t
+#define WT uint32_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u64.rv32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u64.rv32.c
new file mode 100644
index 0000000..9ce64a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u64.rv32.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc -mabi=ilp32 -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint16_t
+#define WT uint64_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u64.rv64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u64.rv64.c
new file mode 100644
index 0000000..517251e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u16-from-u64.rv64.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint16_t
+#define WT uint64_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u128.c
new file mode 100644
index 0000000..4577a88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u128.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint32_t
+#define WT uint128_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u64.rv32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u64.rv32.c
new file mode 100644
index 0000000..59c60b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u64.rv32.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc -mabi=ilp32 -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint32_t
+#define WT uint64_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u64.rv64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u64.rv64.c
new file mode 100644
index 0000000..0d87022
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u32-from-u64.rv64.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint32_t
+#define WT uint64_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u64-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u64-from-u128.c
new file mode 100644
index 0000000..ea26077
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u64-from-u128.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint64_t
+#define WT uint128_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u128.c
new file mode 100644
index 0000000..f0ab76b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u128.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint8_t
+#define WT uint128_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u16.c
new file mode 100644
index 0000000..8ee23d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u16.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint8_t
+#define WT uint16_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u32.c
new file mode 100644
index 0000000..5f08cb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u32.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint8_t
+#define WT uint32_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u64.rv32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u64.rv32.c
new file mode 100644
index 0000000..27388de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u64.rv32.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc -mabi=ilp32 -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint8_t
+#define WT uint64_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u64.rv64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u64.rv64.c
new file mode 100644
index 0000000..fe82715
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-7-u8-from-u64.rv64.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -fdump-tree-optimized" } */
+
+#include "sat_arith.h"
+
+#define NT uint8_t
+#define WT uint64_t
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+/* { dg-final { scan-tree-dump-times ".SAT_MUL" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u128.c
new file mode 100644
index 0000000..1431589
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u128.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint8_t
+#define WT uint128_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u32.c
new file mode 100644
index 0000000..a99fc3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u32.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv32 || rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint16_t
+#define WT uint32_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u64.c
new file mode 100644
index 0000000..fdda5bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u16-from-u64.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv32 || rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint16_t
+#define WT uint64_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u32-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u32-from-u128.c
new file mode 100644
index 0000000..795c9a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u32-from-u128.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint32_t
+#define WT uint128_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u32-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u32-from-u64.c
new file mode 100644
index 0000000..b629df9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u32-from-u64.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv32 || rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint32_t
+#define WT uint64_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u64-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u64-from-u128.c
new file mode 100644
index 0000000..5630a34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u64-from-u128.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint64_t
+#define WT uint128_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u128.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u128.c
new file mode 100644
index 0000000..1431589
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u128.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint8_t
+#define WT uint128_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u16.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u16.c
new file mode 100644
index 0000000..0b4fe23
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u16.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv32 || rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint8_t
+#define WT uint16_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u32.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u32.c
new file mode 100644
index 0000000..bf60a11
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u32.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv32 || rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint8_t
+#define WT uint32_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u64.c b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u64.c
new file mode 100644
index 0000000..c3f9abc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sat/sat_u_mul-run-7-u8-from-u64.c
@@ -0,0 +1,16 @@
+/* { dg-do run { target { rv32 || rv64 } } } */
+/* { dg-additional-options "-std=c99" } */
+
+#include "sat_arith.h"
+#include "sat_arith_data.h"
+
+#define NT uint8_t
+#define WT uint64_t
+#define NAME usmul
+#define DATA TEST_BINARY_DATA_WRAP(NT, NAME)
+#define T TEST_BINARY_STRUCT_DECL_WRAP(NT, NAME)
+#define RUN_BINARY(x, y) RUN_SAT_U_MUL_FMT_6_WRAP(NT, WT, x, y)
+
+DEF_SAT_U_MUL_FMT_6_WRAP(NT, WT)
+
+#include "scalar_sat_binary_run_xxx.h"
diff --git a/libgcobol/charmaps.cc b/libgcobol/charmaps.cc
index 5d43f0b..61481a6 100644
--- a/libgcobol/charmaps.cc
+++ b/libgcobol/charmaps.cc
@@ -94,13 +94,6 @@ char *__gg__ct_currency_signs[256]; // Compile-time currency signs
// And we will take some pains to figure out if the source code file was done
// as UTF-8; if not, we will assume 1252/8859-1
-// __gg__ebcdic_codeset_in_use is the ultimate determinator of whether the
-// internal codeset is ASCII/CP1252 or EBCDIC/CP1140.
-bool __gg__ebcdic_codeset_in_use = false ;
-
-static text_codeset_t source_codeset = cs_cp1252_e;
-static text_codeset_t console_codeset = cs_default_e;
-
#define UNICODE_REPLACEMENT 0xFFFD // This a white question mark in a black diamond
#define ASCII_REPLACEMENT 0x87 // In CP1252, 0x87 is a double-dagger
@@ -235,74 +228,6 @@ __gg__ebcdic_to_cp1252_collation[256] =
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0xFF,
};
-
-// Here is the list of function pointers establish which ones of the paired
-// possibilities of conversion routines are actually in use.
-
-extern "C"
-void __gg__set_internal_codeset(int use_ebcdic)
- {
- __gg__ebcdic_codeset_in_use = !!use_ebcdic;
- }
-
-extern "C"
-void __gg__text_conversion_override(text_device_t device,
- text_codeset_t codeset)
- {
- // Establish the default sourcecode and console codesets, and
- // establish the codeset conversion routines:
-
- switch(device)
- {
- case td_default_e:
- {
- // We are setting our codesets to the defaults
-
- // First, sort out the console:
-
- // It is my understanding that the environment variable LANG is
- // supposed to be set by the terminal to indicate the terminal's
- // current character set. Let's use that as the winner, even if
- // that's not quite the way locale(3) works.
- const char *envLANG = getenv("LANG");
- if( !envLANG )
- {
- // This is odd. No "LANG"?
- envLANG = setlocale(LC_CTYPE, NULL);
- }
- if( !envLANG )
- {
- // This is even more odd. Pick something as a backup to the backup
- envLANG = "UTF-8";
- }
- if( envLANG )
- {
- if( strcasestr(envLANG, "UTF-8") )
- {
- console_codeset = cs_utf8_e;
- }
- else
- {
- // If it isn't UTF-8, then figure on it being CP1252 as a
- // convenient way of specifying an SBC codeset.
- console_codeset = cs_cp1252_e;
- }
- }
- break;
- }
-
- case td_sourcecode_e:
- // Explicitly set the source code codeset:
- source_codeset = codeset;
- break;
-
- case td_console_e:
- // Explicitly set the console codeset:
- console_codeset = codeset;
- break;
- }
- }
-
static encodings_t encodings[] = {
{ iconv_437_e, "437" },
{ iconv_500_e, "500" },
diff --git a/libgcobol/charmaps.h b/libgcobol/charmaps.h
index 15be0ea..4abbfd0 100644
--- a/libgcobol/charmaps.h
+++ b/libgcobol/charmaps.h
@@ -112,8 +112,6 @@ extern char **__gg__currency_signs ;
extern int __gg__default_currency_sign;
extern char *__gg__ct_currency_signs[256]; // Compile-time currency signs
-extern bool __gg__ebcdic_codeset_in_use;
-
#define NULLCH ('\0')
#define DEGENERATE_HIGH_VALUE 0xFF
#define DEGENERATE_LOW_VALUE 0x00
@@ -202,21 +200,6 @@ extern bool __gg__ebcdic_codeset_in_use;
#define ascii_newline ((uint8_t)('\n'))
#define ascii_return ((uint8_t)('\r'))
-enum text_device_t
- {
- td_default_e,
- td_sourcecode_e,
- td_console_e,
- };
-
-enum text_codeset_t
- {
- cs_default_e,
- cs_utf8_e,
- cs_cp1252_e,
- cs_cp1140_e
- };
-
extern unsigned char __gg__data_space[1] ;
extern unsigned char __gg__data_low_values[1] ;
extern unsigned char __gg__data_zeros[1] ;
@@ -234,19 +217,6 @@ extern const unsigned short __gg__cp1140_to_cp1252_values[256];
extern const unsigned short __gg__cp1252_to_ebcdic_collation[256];
extern const unsigned short __gg__ebcdic_to_cp1252_collation[256];
-// As described above, we have a number of operations we need to accomplish. But
-// the actual routines are dependent on whether EBCDIC or ASCII is in use. We
-// implement that by having a function pointer for each function; those pointers
-// are established when the __gg__ebcdic_codeset_in_use variable is established.
-
-// These routines convert a single ASCII character to either ASCII or EBCDIC
-
-extern "C" void __gg__set_internal_codeset(int use_ebcdic);
-
-extern "C"
-void __gg__text_conversion_override(text_device_t device,
- text_codeset_t codeset);
-
const char * __gg__encoding_iconv_name( cbl_encoding_t encoding );
cbl_encoding_t __gg__encoding_iconv_type( const char *name );
diff --git a/libgcobol/gfileio.cc b/libgcobol/gfileio.cc
index 6d3bb5d..16d75b0 100644
--- a/libgcobol/gfileio.cc
+++ b/libgcobol/gfileio.cc
@@ -330,12 +330,6 @@ __gg__file_init(
{
if( !(file->flags & file_flag_initialized_e) )
{
- if( encoding != iconv_CP1140_e && __gg__ebcdic_codeset_in_use )
- {
- // This code is to be eliminated when 'encoding' is valid.
- encoding = iconv_CP1140_e;
- }
-
charmap_t *charmap = __gg__get_charmap(encoding);
file->name = strdup(name);
diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc
index c355051..3d1161c 100644
--- a/libgcobol/libgcobol.cc
+++ b/libgcobol/libgcobol.cc
@@ -139,6 +139,7 @@ int __gg__default_compute_error = 0 ;
int __gg__rdigits = 0 ;
int __gg__nop = 0 ;
int __gg__main_called = 0 ;
+void *__gg__entry_label = NULL ;
cbl_encoding_t __gg__console_encoding = no_encoding_e ;
// During SORT operations, we don't want the end-of-file condition, which
@@ -484,16 +485,7 @@ struct program_state
memset(rt_currency_signs, 0, sizeof(rt_currency_signs));
- // The default collating sequence:
- if( __gg__ebcdic_codeset_in_use )
- {
- rt_collation = __gg__cp1140_to_cp1252_values;
- }
- else
- {
- rt_collation = __gg__one_to_one_values;
- }
-// rt_collation = __gg__one_to_one_values;
+ rt_collation = __gg__one_to_one_values;
rt_program_name = NULL;
}
@@ -694,21 +686,13 @@ void
__gg__pop_program_state()
{
program_states.pop_back();
-
-// #define decimal_point (program_states.back().rt_decimal_point)
-// #define decimal_separator (program_states.back().rt_decimal_separator)
-// #define quote_character (program_states.back().rt_quote_character)
-// #define low_value_character (program_states.back().rt_low_value_character)
-// #define high_value_character (program_states.back().rt_high_value_character)
-
__gg__decimal_point = program_states.back().rt_decimal_point ;
__gg__decimal_separator = program_states.back().rt_decimal_separator ;
__gg__quote_character = program_states.back().rt_quote_character ;
__gg__low_value_character = program_states.back().rt_low_value_character ;
__gg__high_value_character = program_states.back().rt_high_value_character ;
__gg__currency_signs = program_states.back().rt_currency_signs ;
-
-}
+ }
static
int
@@ -10733,7 +10717,8 @@ __gg__set_pointer(cblc_field_t *target,
extern "C"
void
-__gg__alphabet_use( cbl_encoding_t encoding,
+__gg__alphabet_use( cbl_encoding_t alphabetic_encoding,
+ cbl_encoding_t encoding,
size_t alphabet_index)
{
// We simply replace the values in the current program_state. If the
@@ -10743,26 +10728,35 @@ __gg__alphabet_use( cbl_encoding_t encoding,
if( program_states.empty() )
{
// When there is no DATA DIVISION, program_states can be empty when
- // we arrive here. So, we need to remedy that:
+ // we arrive here. So, we need to remedy that.
initialize_program_state();
}
+ const charmap_t *charmap_alphabetic = __gg__get_charmap(alphabetic_encoding);
+
switch( encoding )
{
case ASCII_e:
case iso646_e:
+ // This is one of the very common standard situations; where we are using
+ // something like a CP1252 Western European ASCII-like character set.
+
__gg__low_value_character = DEGENERATE_LOW_VALUE;
__gg__high_value_character = DEGENERATE_HIGH_VALUE;
program_states.back().rt_low_value_character = DEGENERATE_LOW_VALUE;
program_states.back().rt_high_value_character = DEGENERATE_HIGH_VALUE;
- if( !__gg__ebcdic_codeset_in_use )
+ if( !charmap_alphabetic->is_like_ebcdic() )
{
+ // The codeset is ascii-like, and the collation is ascii, so we use
+ // one-to-one values:
program_states.back().rt_collation = __gg__one_to_one_values;
}
else
{
+ // The codeset is ebcdic-like, but the collation is specified as
+ // ascii-like. So, we need that collation:
program_states.back().rt_collation = __gg__ebcdic_to_cp1252_collation;
}
@@ -10774,12 +10768,16 @@ __gg__alphabet_use( cbl_encoding_t encoding,
program_states.back().rt_low_value_character = DEGENERATE_LOW_VALUE;
program_states.back().rt_high_value_character = DEGENERATE_HIGH_VALUE;
- if( __gg__ebcdic_codeset_in_use )
+ if( charmap_alphabetic->is_like_ebcdic() )
{
+ // The alphanumeric codeset is ebcdic-like, and so is the specified
+ // collation:
program_states.back().rt_collation = __gg__one_to_one_values;
}
else
{
+ // The alphanumeric codeset is ebcdic-like, but the specified collation
+ // is ascii-like:
program_states.back().rt_collation = __gg__cp1252_to_ebcdic_collation;
}
break;
diff --git a/libgcobol/valconv.cc b/libgcobol/valconv.cc
index 7d28c90..de4e6f7 100644
--- a/libgcobol/valconv.cc
+++ b/libgcobol/valconv.cc
@@ -79,6 +79,9 @@ __gg__alphabet_create( cbl_encoding_t encoding,
if( it == __gg__alphabet_states.end() )
{
+ // This is an alphabet we don't know about. So just assume the collation
+ // is the same as the character ordering:
+
alphabet_state new_state;
new_state.low_char = low_char;
new_state.high_char = high_char;
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index c292b3f..d88e4c7 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,12 @@
+2025-10-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR c++/119060
+ * include/bits/version.def: Add observable_checkpoint at present
+ allowed from C++26.
+ * include/bits/version.h: Regenerate.
+ * include/std/utility: Add std::observable_checkpoint().
+ * src/c++23/std.cc.in: Add obervable_checkpoint () to utility.
+
2025-10-17 Tomasz KamiƄski <tkaminsk@redhat.com>
* include/bits/atomic_base.h
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 1118da4..f60a518 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1951,6 +1951,15 @@ ftms = {
};
ftms = {
+ name = observable_checkpoint;
+ values = {
+ v = 202506;
+ cxxmin = 26;
+ extra_cond = "__has_builtin(__builtin_observable_checkpoint)";
+ };
+};
+
+ftms = {
name = algorithm_default_value_type;
values = {
v = 202403;
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index c452bbe..cbd82ff 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2181,6 +2181,16 @@
#endif /* !defined(__cpp_lib_unreachable) */
#undef __glibcxx_want_unreachable
+#if !defined(__cpp_lib_observable_checkpoint)
+# if (__cplusplus > 202302L) && (__has_builtin(__builtin_observable_checkpoint))
+# define __glibcxx_observable_checkpoint 202506L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_observable_checkpoint)
+# define __cpp_lib_observable_checkpoint 202506L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_observable_checkpoint) && defined(__glibcxx_want_observable_checkpoint) */
+#undef __glibcxx_want_observable_checkpoint
+
#if !defined(__cpp_lib_algorithm_default_value_type)
# if (__cplusplus > 202302L)
# define __glibcxx_algorithm_default_value_type 202403L
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 8a85ccf..3ae1852 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -98,6 +98,7 @@
#define __glibcxx_want_tuple_element_t
#define __glibcxx_want_tuples_by_type
#define __glibcxx_want_unreachable
+#define __glibcxx_want_observable_checkpoint
#define __glibcxx_want_tuple_like
#define __glibcxx_want_constrained_equality
#include <bits/version.h>
@@ -234,6 +235,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif
+
+#ifdef __cpp_lib_observable_checkpoint // C++ >= 26
+ /// Informs the compiler that prior actions are considered observable.
+ /**
+ * This may be used to limit the extent to which optimisations based on the
+ * assumed unreachability of undefined behaviour can propagate to earlier
+ * code.
+ *
+ * @since C++26
+ */
+ [[__gnu__::__always_inline__]]
+ inline void
+ observable_checkpoint() noexcept
+ {
+ return __builtin_observable_checkpoint();
+ }
+#endif
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/std.cc.in
index 9cf5fa7..e849307 100644
--- a/libstdc++-v3/src/c++23/std.cc.in
+++ b/libstdc++-v3/src/c++23/std.cc.in
@@ -3337,6 +3337,9 @@ export namespace std
#if __cpp_lib_unreachable
using std::unreachable;
#endif
+#if __cpp_lib_observable_checkpoint
+ using std::observable_checkpoint;
+#endif
}
// <valarray>