This removes the last real _Float128 as the return value of numstr2i.
Following Jakubs changes I refrained from trying to refactor this
in a way to avoid the int->_Float128->int round-trips we do in many
places but replace _Float128 with REAL_VALUE_TYPE.
Tested on x86_64-unknown-linux-gnu. OK?
* parse.y (numstr2i): Return a REAL_VALUE_TYPE. Refactor
the boolean_e case to a single return point.
(<clauses>): Adjust numstr2i uses.
---
gcc/cobol/parse.y | 86 +++++++++++++++++++++++++++--------------------
1 file changed, 50 insertions(+), 36 deletions(-)
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index 99deeda217b..43ecef0de8f 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -206,7 +206,7 @@
static data_category_t
data_category_of( const cbl_refer_t& refer );
- static _Float128
+ static REAL_VALUE_TYPE
numstr2i( const char input[], radix_t radix );
struct cbl_field_t;
@@ -2916,22 +2916,26 @@ fd_clause: record_desc
block_desc: BLOCK_kw contains rec_contains chars_recs
;
rec_contains: NUMSTR[min] {
- ssize_t n;
- if( (n = numstr2i($min.string, $min.radix)) < 0 ) {
+ REAL_VALUE_TYPE rn = numstr2i($min.string, $min.radix);
+ ssize_t n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@min, "size %s cannot be negative", $min.string);
YYERROR;
}
$$.min = $$.max = n; // fixed length
}
| NUMSTR[min] TO NUMSTR[max] {
- ssize_t n;
- if( (n = numstr2i($min.string, $min.radix)) < 0 ) {
+ REAL_VALUE_TYPE rn = numstr2i($min.string, $min.radix);
+ ssize_t n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@min, "size %s cannot be negative", $min.string);
YYERROR;
}
$$.min = n;
- if( (n = numstr2i($max.string, $max.radix)) < 0 ) {
+ rn = numstr2i($max.string, $max.radix);
+ n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@max, "size %s cannot be negative", $max.string);
YYERROR;
}
@@ -2990,26 +2994,32 @@ in_size: IN SIZE
;
from_to: FROM NUMSTR[min] TO NUMSTR[max] characters {
- ssize_t n;
- if( (n = numstr2i($min.string, $min.radix)) < 0 ) {
+ REAL_VALUE_TYPE rn = numstr2i($min.string, $min.radix);
+ ssize_t n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@min, "size %s cannot be negative", $min.string);
YYERROR;
}
$$.min = n;
- if( (n = numstr2i($max.string, $max.radix)) < 0 ) {
+ rn = numstr2i($max.string, $max.radix);
+ n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@min, "size %s cannot be negative", $max.string);
YYERROR;
}
$$.max = n;
}
| NUMSTR[min] TO NUMSTR[max] characters {
- ssize_t n;
- if( (n = numstr2i($min.string, $min.radix)) < 0 ) {
+ REAL_VALUE_TYPE rn = numstr2i($min.string, $min.radix);
+ ssize_t n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@min, "size %s cannot be negative", $min.string);
YYERROR;
}
$$.min = n;
- if( (n = numstr2i($max.string, $max.radix)) < 0 ) {
+ rn = numstr2i($max.string, $max.radix);
+ n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@max, "size %s cannot be negative", $max.string);
YYERROR;
}
@@ -3017,8 +3027,9 @@ from_to: FROM NUMSTR[min] TO NUMSTR[max]
characters {
}
| TO NUMSTR[max] characters {
- ssize_t n;
- if( (n = numstr2i($max.string, $max.radix)) < 0 ) {
+ REAL_VALUE_TYPE rn = numstr2i($max.string, $max.radix);
+ ssize_t n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@max, "size %s cannot be negative", $max.string);
YYERROR;
}
@@ -3027,8 +3038,9 @@ from_to: FROM NUMSTR[min] TO NUMSTR[max]
characters {
}
| FROM NUMSTR[min] characters {
- ssize_t n;
- if( (n = numstr2i($min.string, $min.radix)) < 0 ) {
+ REAL_VALUE_TYPE rn = numstr2i($min.string, $min.radix);
+ ssize_t n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@min, "size %s cannot be negative", $min.string);
YYERROR;
}
@@ -3036,8 +3048,9 @@ from_to: FROM NUMSTR[min] TO NUMSTR[max]
characters {
$$.max = size_t(-1);
}
| NUMSTR[min] characters {
- ssize_t n;
- if( (n = numstr2i($min.string, $min.radix)) < 0 ) {
+ REAL_VALUE_TYPE rn = numstr2i($min.string, $min.radix);
+ ssize_t n = real_to_integer (&rn);
+ if( n < 0 ) {
error_msg(@min, "size %s cannot be negative", $min.string);
YYERROR;
}
@@ -3170,7 +3183,8 @@ cardinal_lb: cardinal times {
cardinal: NUMSTR[input]
{
- $$ = numstr2i( $input.string, $input.radix );
+ REAL_VALUE_TYPE rn = numstr2i($input.string, $input.radix);
+ $$ = real_to_integer (&rn);
}
;
@@ -4120,7 +4134,8 @@ nines: NINES
count: %empty { $$ = 0; }
| '(' NUMSTR ')'
{
- $$ = numstr2i( $NUMSTR.string, $NUMSTR.radix );
+ REAL_VALUE_TYPE rn = numstr2i($NUMSTR.string, $NUMSTR.radix);
+ $$ = real_to_integer (&rn);
if( $$ == 0 ) {
error_msg(@2, "'(0)' invalid in PICTURE (ISO 2023
13.18.40.3)");
}
@@ -6920,9 +6935,7 @@ cce_expr: cce_factor
;
cce_factor: NUMSTR {
- /* ??? real_from_string does not allow arbitrary radix. */
- // $$ = numstr2i($1.string, $1.radix);
- real_from_string (&$$, $1.string);
+ $$ = numstr2i($1.string, $1.radix);
}
;
@@ -12048,10 +12061,10 @@ valid_target( const cbl_refer_t& refer ) {
return false;
}
-static _Float128
+static REAL_VALUE_TYPE
numstr2i( const char input[], radix_t radix ) {
- _Float128 output = 0.0;
- size_t bit, integer = 0;
+ REAL_VALUE_TYPE output;
+ size_t integer = 0;
int erc=0, n=0;
switch( radix ) {
@@ -12059,33 +12072,34 @@ numstr2i( const char input[], radix_t radix ) {
auto local = xstrdup(input), pend = local;
if( !local ) { erc = -1; break; }
std::replace(local, local + strlen(local), ',', '.');
- output = strtof128(local, &pend);
+ real_from_string3 (&output, local, TYPE_MODE (float128_type_node));
+ strtof128(local, &pend);
n = pend - local;
}
break;
case hexadecimal_e:
erc = sscanf(input, "%zx%n", &integer, &n);
- output = integer;
+ real_from_integer (&output, VOIDmode, integer, UNSIGNED);
break;
case boolean_e:
for( const char *p = input; *p != '\0'; p++ ) {
if( ssize_t(8 * sizeof(integer) - 1) < p - input ) {
yywarn("'%s' was accepted as %d", input, integer);
- return integer;
+ break;
}
switch(*p) {
- case '0': bit = 0; break;
- case '1': bit = 1; break;
+ case '0':
+ case '1':
+ integer = (integer << (p - input));
+ integer |= ((*p) == '0' ? 0 : 1);
break;
default:
yywarn("'%s' was accepted as %d", input, integer);
- return integer;
+ break;
}
- integer = (integer << (p - input));
- integer |= bit;
}
- return integer;
- break;
+ real_from_integer (&output, VOIDmode, integer, UNSIGNED);
+ return output;
}
if( erc == -1 || n < int(strlen(input)) ) {
yywarn("'%s' was accepted as %lld", input, output);
--
2.43.0