> Am 09.04.2025 um 23:19 schrieb Robert Dubner <rdub...@symas.com>:
>
> This patch eliminates the error.
>
> cobol: Proper comparison of alphanumeric to refmoded numeric-display
> [PR119682]
Can you add the testcase as part of the fix?
> gcc/cobol
>
> PR cobol/119682
> * genapi.cc: (cobol_compare): Change the call to
> __gg__compare().
>
> libgcobol
>
> PR cobol/119682
> * common-defs.h: Define the REFER_T_REFMOD constant.
> * intrinsic.cc: (__gg__max): Change the calls to
> __gg__compare_2(),
> (__gg__min): Likewise, (__gg__ord_min): Likewise,
> (__gg__ord_max): Likewise.
> * libgcobol.cc: (__gg__compare_2): Change definition of
> calling
> parameters, eliminate separate flag bit for ALL and
> ADDRESS_OF,
> change comparison of alphanumeric to numeric when the numeric
> is a refmod.
> * libgcobol.h: Change declaration of __gg__compare_2.
>
> diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
> index c91237bd8d2c..fdf76aad7b14 100644
> --- a/gcc/cobol/genapi.cc
> +++ b/gcc/cobol/genapi.cc
> @@ -2028,10 +2028,12 @@ cobol_compare( tree return_int,
> {
> // None of our explicit comparisons up above worked, so we revert to
> the
> // general case:
> - int leftflags = (left_side_ref.all ? REFER_T_MOVE_ALL : 0)
> - + (left_side_ref.addr_of ? REFER_T_ADDRESS_OF : 0);
> - int rightflags = (right_side_ref.all ? REFER_T_MOVE_ALL : 0)
> - + (right_side_ref.addr_of ? REFER_T_ADDRESS_OF : 0);
> + int leftflags = (left_side_ref.all ? REFER_T_MOVE_ALL :
> 0)
> + + (left_side_ref.addr_of ? REFER_T_ADDRESS_OF :
> 0)
> + + (left_side_ref.refmod.from ? REFER_T_REFMOD :
> 0);
> + int rightflags = (right_side_ref.all ? REFER_T_MOVE_ALL :
> 0)
> + + (right_side_ref.addr_of ? REFER_T_ADDRESS_OF :
> 0)
> + + (right_side_ref.refmod.from ? REFER_T_REFMOD :
> 0);
> gg_assign( return_int, gg_call_expr(
> INT,
> "__gg__compare",
> @@ -2045,6 +2047,7 @@ cobol_compare( tree return_int,
> build_int_cst_type(INT, rightflags),
> integer_zero_node,
> NULL_TREE));
> + compared = true;
> }
>
> // gg_printf(" result is %d\n", return_int, NULL_TREE);
> diff --git a/libgcobol/common-defs.h b/libgcobol/common-defs.h
> index f9d9c56a0d8d..6bf32ef79cf0 100644
> --- a/libgcobol/common-defs.h
> +++ b/libgcobol/common-defs.h
> @@ -70,6 +70,7 @@
> #define REFER_T_ALL_FLAGS_MASK 0x0FF // We allow for seven subscripts
> #define REFER_T_MOVE_ALL 0x100 // This is the move_all flag
> #define REFER_T_ADDRESS_OF 0x200 // This is the address_of flag
> +#define REFER_T_REFMOD 0x400 // Indicates to library the refer
> was a refmod
>
> #define MIN_FIELD_BLOCK_SIZE (16)
>
> diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc
> index 4bce481b0c04..e0bd3339708e 100644
> --- a/libgcobol/intrinsic.cc
> +++ b/libgcobol/intrinsic.cc
> @@ -1867,8 +1867,7 @@ __gg__max(cblc_field_t *dest,
> unsigned char *best_location ;
> size_t best_length ;
> int best_attr ;
> - bool best_move_all ;
> - bool best_address_of ;
> + int best_flags ;
>
> bool first_time = true;
> assert(ncount);
> @@ -1887,8 +1886,7 @@ __gg__max(cblc_field_t *dest,
> best_location = __gg__treeplet_1f[i]->data +
> __gg__treeplet_1o[i];
> best_length = __gg__treeplet_1s[i];
> best_attr = __gg__treeplet_1f[i]->attr;
> - best_move_all = !!(__gg__fourplet_flags[i] &
> REFER_T_MOVE_ALL);
> - best_address_of = !!(__gg__fourplet_flags[i] &
> REFER_T_ADDRESS_OF);
> + best_flags = __gg__fourplet_flags[i];
> }
> else
> {
> @@ -1896,31 +1894,27 @@ __gg__max(cblc_field_t *dest,
> unsigned char *candidate_location =
> __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i];
> size_t candidate_length = __gg__treeplet_1s[i];
> int candidate_attr =
> __gg__treeplet_1f[i]->attr;
> - bool candidate_move_all =
> !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL);
> - bool candidate_address_of =
> !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF);
> + int candidate_flags = __gg__fourplet_flags[i];
>
> int compare_result = __gg__compare_2(
> candidate_field,
> candidate_location,
> candidate_length,
> candidate_attr,
> - candidate_move_all,
> - candidate_address_of,
> + candidate_flags,
> best_field,
> best_location,
> best_length,
> best_attr,
> - best_move_all,
> - best_address_of,
> + best_flags,
> 0);
> if( compare_result >= 0 )
> {
> - best_field = candidate_field ;
> - best_location = candidate_location ;
> - best_length = candidate_length ;
> - best_attr = candidate_attr ;
> - best_move_all = candidate_move_all ;
> - best_address_of = candidate_address_of ;
> + best_field = candidate_field ;
> + best_location = candidate_location ;
> + best_length = candidate_length ;
> + best_attr = candidate_attr ;
> + best_flags = candidate_flags ;
> }
> }
> if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) )
> @@ -2129,8 +2123,7 @@ __gg__min(cblc_field_t *dest,
> unsigned char *best_location ;
> size_t best_length ;
> int best_attr ;
> - bool best_move_all ;
> - bool best_address_of ;
> + int best_flags ;
>
> bool first_time = true;
> assert(ncount);
> @@ -2149,8 +2142,7 @@ __gg__min(cblc_field_t *dest,
> best_location = __gg__treeplet_1f[i]->data +
> __gg__treeplet_1o[i];
> best_length = __gg__treeplet_1s[i];
> best_attr = __gg__treeplet_1f[i]->attr;
> - best_move_all = !!(__gg__fourplet_flags[i] &
> REFER_T_MOVE_ALL);
> - best_address_of = !!(__gg__fourplet_flags[i] &
> REFER_T_ADDRESS_OF);
> + best_flags = __gg__fourplet_flags[i];
> }
> else
> {
> @@ -2158,31 +2150,27 @@ __gg__min(cblc_field_t *dest,
> unsigned char *candidate_location =
> __gg__treeplet_1f[i]->data + __gg__treeplet_1o[i];
> size_t candidate_length = __gg__treeplet_1s[i];
> int candidate_attr =
> __gg__treeplet_1f[i]->attr;
> - bool candidate_move_all =
> !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL);
> - bool candidate_address_of =
> !!(__gg__fourplet_flags[i] & REFER_T_ADDRESS_OF);
> + int candidate_flags = __gg__fourplet_flags[i];
>
> int compare_result = __gg__compare_2(
> candidate_field,
> candidate_location,
> candidate_length,
> candidate_attr,
> - candidate_move_all,
> - candidate_address_of,
> + candidate_flags,
> best_field,
> best_location,
> best_length,
> best_attr,
> - best_move_all,
> - best_address_of,
> + best_flags,
> 0);
> if( compare_result < 0 )
> {
> - best_field = candidate_field ;
> - best_location = candidate_location ;
> - best_length = candidate_length ;
> - best_attr = candidate_attr ;
> - best_move_all = candidate_move_all ;
> - best_address_of = candidate_address_of ;
> + best_field = candidate_field ;
> + best_location = candidate_location ;
> + best_length = candidate_length ;
> + best_attr = candidate_attr ;
> + best_flags = candidate_flags ;
> }
> }
> if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) )
> @@ -2991,14 +2979,12 @@ __gg__ord_min(cblc_field_t *dest,
> unsigned char *best_location;
> size_t best_length;
> int best_attr;
> - bool best_move_all;
> - bool best_address_of ;
> + int best_flags;
>
> unsigned char *candidate_location;
> size_t candidate_length;
> int candidate_attr;
> - bool candidate_move_all;
> - bool candidate_address_of;
> + int candidate_flags;
>
> for( size_t i=0; i<ninputs; i++ )
> {
> @@ -3016,8 +3002,7 @@ __gg__ord_min(cblc_field_t *dest,
> best_location = __gg__treeplet_1f[i]->data +
> __gg__treeplet_1o[i];
> best_length = __gg__treeplet_1s[i];
> best_attr = __gg__treeplet_1f[i]->attr;
> - best_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL);
> - best_address_of = !!(__gg__fourplet_flags[i] &
> REFER_T_ADDRESS_OF);
> + best_flags = __gg__fourplet_flags[i];
> }
> else
> {
> @@ -3026,8 +3011,7 @@ __gg__ord_min(cblc_field_t *dest,
> candidate_location = __gg__treeplet_1f[i]->data +
> __gg__treeplet_1o[i];
> candidate_length = __gg__treeplet_1s[i];
> candidate_attr = __gg__treeplet_1f[i]->attr;
> - candidate_move_all = !!(__gg__fourplet_flags[i] &
> REFER_T_MOVE_ALL);
> - candidate_address_of = !!(__gg__fourplet_flags[i] &
> REFER_T_ADDRESS_OF);
> + candidate_flags = __gg__fourplet_flags[i];
>
> int compare_result =
> __gg__compare_2(
> @@ -3035,14 +3019,12 @@ __gg__ord_min(cblc_field_t *dest,
> candidate_location,
> candidate_length,
> candidate_attr,
> - candidate_move_all,
> - candidate_address_of,
> + candidate_flags,
> best,
> best_location,
> best_length,
> best_attr,
> - best_move_all,
> - best_address_of,
> + best_flags,
> 0);
> if( compare_result < 0 )
> {
> @@ -3051,8 +3033,7 @@ __gg__ord_min(cblc_field_t *dest,
> best_location = candidate_location;
> best_length = candidate_length;
> best_attr = candidate_attr;
> - best_move_all = candidate_move_all;
> - best_address_of = candidate_address_of;
> + best_flags = candidate_flags;
> }
> }
> if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) )
> @@ -3086,14 +3067,12 @@ __gg__ord_max(cblc_field_t *dest,
> unsigned char *best_location;
> size_t best_length;
> int best_attr;
> - bool best_move_all;
> - bool best_address_of ;
> + int best_flags;
>
> unsigned char *candidate_location;
> size_t candidate_length;
> int candidate_attr;
> - bool candidate_move_all;
> - bool candidate_address_of;
> + int candidate_flags;
>
> for( size_t i=0; i<ninputs; i++ )
> {
> @@ -3111,8 +3090,7 @@ __gg__ord_max(cblc_field_t *dest,
> best_location = __gg__treeplet_1f[i]->data +
> __gg__treeplet_1o[i];
> best_length = __gg__treeplet_1s[i];
> best_attr = __gg__treeplet_1f[i]->attr;
> - best_move_all = !!(__gg__fourplet_flags[i] & REFER_T_MOVE_ALL);
> - best_address_of = !!(__gg__fourplet_flags[i] &
> REFER_T_ADDRESS_OF);
> + best_flags = __gg__fourplet_flags[i];
> }
> else
> {
> @@ -3121,8 +3099,7 @@ __gg__ord_max(cblc_field_t *dest,
> candidate_location = __gg__treeplet_1f[i]->data +
> __gg__treeplet_1o[i];
> candidate_length = __gg__treeplet_1s[i];
> candidate_attr = __gg__treeplet_1f[i]->attr;
> - candidate_move_all = !!(__gg__fourplet_flags[i] &
> REFER_T_MOVE_ALL);
> - candidate_address_of = !!(__gg__fourplet_flags[i] &
> REFER_T_ADDRESS_OF);
> + candidate_flags = __gg__fourplet_flags[i];
>
> int compare_result =
> __gg__compare_2(
> @@ -3130,14 +3107,12 @@ __gg__ord_max(cblc_field_t *dest,
> candidate_location,
> candidate_length,
> candidate_attr,
> - candidate_move_all,
> - candidate_address_of,
> + candidate_flags,
> best,
> best_location,
> best_length,
> best_attr,
> - best_move_all,
> - best_address_of,
> + best_flags,
> 0);
> if( compare_result > 0 )
> {
> @@ -3146,8 +3121,7 @@ __gg__ord_max(cblc_field_t *dest,
> best_location = candidate_location;
> best_length = candidate_length;
> best_attr = candidate_attr;
> - best_move_all = candidate_move_all;
> - best_address_of = candidate_address_of;
> + best_flags = candidate_flags;
> }
> }
> if( !update_refer_state_for_all(state, __gg__treeplet_1f[i]) )
> diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc
> index c163e2c92f2b..f7fa7a7527b9 100644
> --- a/libgcobol/libgcobol.cc
> +++ b/libgcobol/libgcobol.cc
> @@ -3919,23 +3919,17 @@ __gg__compare_2(cblc_field_t *left_side,
> unsigned char *left_location,
> size_t left_length,
> int left_attr,
> - bool left_all,
> - bool left_address_of,
> + int left_flags,
> cblc_field_t *right_side,
> unsigned char *right_location,
> size_t right_length,
> int right_attr,
> - bool right_all,
> - bool right_address_of,
> + int right_flags,
> int second_time_through)
> {
> // First order of business: If right_side is a FldClass, pass that off
> // to the speciality squad:
>
> - // static size_t converted_initial_size = MINIMUM_ALLOCATION_SIZE;
> - // static unsigned char *converted_initial =
> - // (unsigned char
> *)malloc(converted_initial_size);
> -
> if( right_side->type == FldClass )
> {
> return compare_field_class( left_side,
> @@ -3945,8 +3939,17 @@ __gg__compare_2(cblc_field_t *left_side,
> }
>
> // Serene in our conviction that the left_side isn't a FldClass, we
> - // move on:
> + // move on.
> +
> + // Extract the individual flags from the flag words:
> + bool left_all = !!(left_flags & REFER_T_MOVE_ALL );
> + bool left_address_of = !!(left_flags & REFER_T_ADDRESS_OF);
> + bool right_all = !!(right_flags & REFER_T_MOVE_ALL );
> + bool right_address_of = !!(right_flags & REFER_T_ADDRESS_OF);
> +//bool left_refmod = !!(left_flags & REFER_T_REFMOD );
> + bool right_refmod = !!(right_flags & REFER_T_REFMOD );
>
> + // Figure out if we have any figurative constants
> cbl_figconst_t left_figconst = (cbl_figconst_t)(left_attr &
> FIGCONST_MASK);
> cbl_figconst_t right_figconst = (cbl_figconst_t)(right_attr &
> FIGCONST_MASK);
>
> @@ -4302,6 +4305,23 @@ __gg__compare_2(cblc_field_t *left_side,
> {
> // We are comparing an alphanumeric to a numeric.
>
> + // The right side is numeric. Sometimes people write code where
> they
> + // take the refmod of a numeric displays. If somebody did that
> here,
> + // just do a complete straight-up character by character
> comparison:
> +
> + if( right_refmod )
> + {
> + retval = compare_strings( (char *)left_location,
> + left_length,
> + left_all,
> + (char *)right_location,
> + right_length,
> + right_all);
> + compare = true;
> + goto fixup_retval;
> + }
> +
> +
> // The trick here is to convert the numeric to its display form,
> // and compare that to the alphanumeric. For example, when
> comparing
> // a VAL5 PIC X(3) VALUE 5 to literals,
> @@ -4310,7 +4330,6 @@ __gg__compare_2(cblc_field_t *left_side,
> // VAL5 EQUAL 005 is TRUE
> // VAL5 EQUAL "5" is FALSE
> // VAL5 EQUAL "005" is TRUE
> -
> if( left_side->type == FldLiteralA )
> {
> left_location = (unsigned char *)left_side->data;
> @@ -4373,14 +4392,12 @@ fixup_retval:
> right_location,
> right_length,
> right_attr,
> - right_all,
> - right_address_of,
> + right_flags,
> left_side,
> left_location,
> left_length,
> left_attr,
> - left_all,
> - left_address_of,
> + left_flags,
> 1);
> // And reverse the sense of the return value:
> compare = true;
> @@ -4428,14 +4445,12 @@ __gg__compare(struct cblc_field_t *left,
> left->data + left_offset,
> left_length,
> left->attr,
> - !!(left_flags & REFER_T_MOVE_ALL),
> - !!(left_flags & REFER_T_ADDRESS_OF),
> + left_flags,
> right,
> right->data + right_offset,
> right_length,
> right->attr,
> - !!(right_flags & REFER_T_MOVE_ALL),
> - !!(right_flags & REFER_T_ADDRESS_OF),
> + right_flags,
> second_time_through);
> return retval;
> }
> diff --git a/libgcobol/libgcobol.h b/libgcobol/libgcobol.h
> index 1fc7abc931a4..246ef5114955 100644
> --- a/libgcobol/libgcobol.h
> +++ b/libgcobol/libgcobol.h
> @@ -54,14 +54,12 @@ extern "C" int __gg__compare_2( cblc_field_t
> *left_side,
> unsigned char *left_location,
> size_t left_length,
> int left_attr,
> - bool left_all,
> - bool left_address_of,
> + int left_flags,
> cblc_field_t *right_side,
> unsigned char *right_location,
> size_t right_length,
> int right_attr,
> - bool right_all,
> - bool right_address_of,
> + int right_flags,
> int second_time_through);
> extern "C" void __gg__int128_to_field(cblc_field_t *tgt,
> __int128 value,
> bob@doobie:~/repos/gcc-cobol$