cobol: Proper comparison of alphanumeric to refmoded numeric-display [PR119682]

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.
This commit is contained in:
Bob Dubner 2025-04-09 16:23:53 -04:00 committed by Robert Dubner
parent f7738c3671
commit 6704d95ec8
5 changed files with 77 additions and 86 deletions

View file

@ -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);

View file

@ -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)

View file

@ -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]) )

View file

@ -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;
}

View file

@ -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,