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

Reply via email to