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