> -----Original Message-----
> From: Richard Biener <rguent...@suse.de>
> Sent: Monday, March 24, 2025 05:04
> To: Robert Dubner <rdub...@symas.com>
> Cc: Jakub Jelinek <ja...@redhat.com>; gcc-patches@gcc.gnu.org
> Subject: RE: [PATCH] change cbl_field_data_t::etc_t::value from
_Float128
> to tree
> 
> On Sun, 23 Mar 2025, Robert Dubner wrote:
> 
> > I am enclosing a patch to be applied on top of yours.  (Your patch got
> us
> > down to zero errors in the "Coughlan" tests, 2 UAT errors, and 4
errors
> in
> > the NIST tests.  Well done!)
> >
> > This one passes all of my tests, in both ASCII and EBCDIC forms.  It
> also
> > passes "make check-cobol".  That's on my x_86_64-linux machine.
> >
> > (That's the good news.  The bad news is that this is exposing gaps in
> > coverage of our test suites.  There is stuff that the misnamed
numstr2i
> > routine used to do that isn't being done, but no errors are flagged in
> any
> > test.)
> >
> > Given that this version passes everything that our regression tests
> cover,
> > is it time to accumulate all this work into a single patch and have
that
> > committed?
> 
> That would be nice, it's difficult to keep track of all the things in
> flight.  And thanks Jakub for picking up the ball while I was
> weekending in the German wilderness ;)
> 
> I was also wondering of adding test coverage for the various paths we're
> touching.

I am creating a process whereby I selectively convert many of our UAT
tests to the DejaGnu format.  I just today sent a bug report to Jakub.  I
am having trouble making the new gd-output-file directive he so graciously
created work, and I need that for the process.

Bob D.

> 
> Richard.
> 
> > Perhaps I should create that patch, seeing as how at this moment only
I
> > can do all of my known tests.
> >
> > Bob D.
> >
> >
> > diff --git a/gcc/cobol/UAT/testsuite.src/syn_definition.at
> > b/gcc/cobol/UAT/testsuite.src/syn_definition.at
> > index 787468a194ff..6547b59955ab 100644
> > --- a/gcc/cobol/UAT/testsuite.src/syn_definition.at
> > +++ b/gcc/cobol/UAT/testsuite.src/syn_definition.at
> > @@ -535,7 +535,7 @@ prog.cob:44:20: error: invalid picture for
> > Alphanumeric-edited
> >  prog.cob:67:22: error: PICTURE '(str-constant)' requires a CONSTANT
> value
> >     67 |            03  PIC X(str-constant).
> >        |                      ^
> > -prog.cob:69:22: error: invalid PICTURE count
> > '(-1.00000000000000000000000000000000E+00)'
> > +prog.cob:69:22: error: invalid PICTURE count '(signed-constant)'
> >     69 |            03  PIC X(signed-constant).
> >        |                      ^
> >  prog.cob:69:21: error: PICTURE count '(-1)' is negative
> > diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
> > index ca86ffa2fc74..f3cab0a4ad1e 100644
> > --- a/gcc/cobol/genapi.cc
> > +++ b/gcc/cobol/genapi.cc
> > @@ -4897,8 +4897,7 @@ parser_display_internal(tree file_descriptor,
> >        }
> >      else
> >        {
> > -      p += 1;
> > -      int exp = atoi(p);
> > +      int exp = atoi(p+1);
> >        if( exp >= 6 || exp <= -5 )
> >     {
> >     // We are going to stick with the E notation, so ach has our
> > result
> > diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
> > index 0077863d766b..c2fe2d8d2265 100644
> > --- a/gcc/cobol/parse.y
> > +++ b/gcc/cobol/parse.y
> > @@ -6935,6 +6935,17 @@ cce_expr:       cce_factor
> >  cce_factor:     NUMSTR {
> >                    /* ???  real_from_string does not allow arbitrary
> > radix.  */
> >                    // $$ = numstr2i($1.string, $1.radix);
> > +                  // When DECIMAL IS COMMA, commas act as decimal
> points.
> > +                  // What follows is an expedient hack; the numstr2i
> > routine
> > +                  // actually needs to be fixed.
> > +                  for(size_t i=0; i<strlen($1.string); i++)
> > +                    {
> > +                    if( $1.string[i] == ',' )
> > +                      {
> > +                      $1.string[i] = '.';
> > +                      }
> > +                    }
> > +                  // End of hack
> >               real_from_string3 (&$$, $1.string,
> >                                  TYPE_MODE (float128_type_node));
> >                  }
> > @@ -12894,14 +12905,14 @@ literal_refmod_valid( YYLTYPE loc, const
> > cbl_refer_t& r ) {
> >      if( ! is_literal(refmod.len->field) ) return true;
> >      auto edge = real_to_integer (TREE_REAL_CST_PTR
> > (refmod.len->field->data.value_of()));
> >      if( 0 < edge ) {
> > -      if( --edge < r.field->data.capacity ) return true;
> > +      if( edge-1 < r.field->data.capacity ) return true;
> >      }
> >      // len < 0 or not: 0 < from + len <= capacity
> >      error_msg(loc, "%s(%s:%zu) out of bounds, "
> >                "size is %u",
> >           r.field->name,
> >           refmod.from->name(),
> > -         size_t(refmod.len->field->data.value_of()),
> > +         size_t(edge),
> >           static_cast<unsigned int>(r.field->data.capacity) );
> >      return false;
> >    }
> > @@ -12930,7 +12941,7 @@ literal_refmod_valid( YYLTYPE loc, const
> > cbl_refer_t& r ) {
> >    // not: 0 < from <= capacity
> >    error_msg(loc,"%s(%zu) out of bounds, size is %u",
> >         r.field->name,
> > -       size_t(refmod.from->field->data.value_of()),
> > +       size_t(real_to_integer (TREE_REAL_CST_PTR
> > (refmod.from->field->data.value_of()))),
> >         static_cast<unsigned int>(r.field->data.capacity) );
> >    return false;
> >  }
> > diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc
> > index e078412e4eac..f9055c62497e 100644
> > --- a/gcc/cobol/symbols.cc
> > +++ b/gcc/cobol/symbols.cc
> > @@ -4511,6 +4511,7 @@ cbl_occurs_t::subscript_ok( const cbl_field_t
> > *subscript ) const {
> >    if( subscript->type != FldLiteralN ) return false;
> >
> >    // ???  This only gets us int64_t
> > +  // Answer: Array subscripts up to 2^64-1 seem to be a great
> > sufficiency.
> >    auto sub = real_to_integer (TREE_REAL_CST_PTR
> > (subscript->data.value_of()));
> >    REAL_VALUE_TYPE csub;
> >    real_from_integer (&csub, VOIDmode, sub, SIGNED);
> >
> > > -----Original Message-----
> > > From: Jakub Jelinek <ja...@redhat.com>
> > > Sent: Sunday, March 23, 2025 06:43
> > > To: Robert Dubner <rdub...@symas.com>
> > > Cc: Richard Biener <rguent...@suse.de>; gcc-patches@gcc.gnu.org
> > > Subject: Re: [PATCH] change cbl_field_data_t::etc_t::value from
> > _Float128
> > > to tree
> > >
> > > On Sat, Mar 22, 2025 at 11:25:13PM -0500, Robert Dubner wrote:
> > > > Real progress here.  Preliminary report:
> > > >
> > > > I am still seeing trouble with a PIC PP9 variable coming back .000
> > > instead
> > > > of 0.001.
> > > >
> > > > In my 679 UAT tests, the failure count is down from 23 to 4
> > > >
> > > > In the NIST tests, the failure count is down from 273 to 35
> > >
> > > Nice.
> > >
> > > > It's after midnight, and my daily chores are not done, so I can't
> > really
> > > > look into all of the failures.
> > > >
> > > > Here's one, though:
> > > >
> > > >         IDENTIFICATION DIVISION.
> > > >         PROGRAM-ID.  numeds.
> > > >         DATA DIVISION.
> > > >         WORKING-STORAGE SECTION.
> > > >         01 VARPP9 PIC PP9 VALUE 0.001.
> > > >         01 VARP9  PIC P9  VALUE 0.01.
> > > >         01 VARV9  PIC V9  VALUE 0.1.
> > > >         01 VAR9   PIC 9   VALUE 1.
> > > >         01 VAR9P  PIC 9P  VALUE 10.
> > > >         01 VAR9PP PIC 9PP VALUE 100.
> > > >         PROCEDURE DIVISION.
> > > >             DISPLAY "VARPP9 should be .001 is "  VARPP9
> > > >             DISPLAY "VARP9  should be .01  is "  VARP9
> > > >             DISPLAY "VARV9  should be .1   is "  VARV9
> > > >             DISPLAY "VAR9   should be 1    is "  VAR9
> > > >             DISPLAY "VAR9P  should be 10   is "  VAR9P
> > > >             DISPLAY "VAR9PP should be 100  is "  VAR9PP.
> > > >         END PROGRAM numeds.
> > > >
> > > > What I am seeing with your patch is
> > > >
> > > > VARPP9 should be .001 is .000
> > > > VARP9  should be .01  is .01
> > > > VARV9  should be .1   is .1
> > > > VAR9   should be 1    is 1
> > > > VAR9P  should be 10   is 10
> > > > VAR9PP should be 100  is 100
> > >
> > > Ok, here is another incremental patch (so you need Richi's patch
> > > + my incremental you were testing + this one) for this:
> > >
> > > --- gcc/cobol/genapi.cc.jj        2025-03-22 08:21:18.287554771
+0100
> > > +++ gcc/cobol/genapi.cc   2025-03-23 11:38:04.757439095 +0100
> > > @@ -53,6 +53,7 @@
> > >  #include "../../libgcobol/valconv.h"
> > >  #include "show_parse.h"
> > >  #include "fold-const.h"
> > > +#include "realmpfr.h"
> > >
> > >  extern int yylineno;
> > >
> > > @@ -15284,22 +15285,36 @@ binary_initial_from_float128(cbl_field_t
> > >      {
> > >        REAL_VALUE_TYPE pow10 = real_powi10 (rdigits);
> > >        real_arithmetic (&value, MULT_EXPR, &value, &pow10);
> > > -      // But make sure to round properly
> > > -      real_roundeven (&value, VOIDmode, &value);
> > > +      real_convert (&value, TYPE_MODE (float128_type_node),
&value);
> > >      }
> > >    // We need to make sure that the resulting string will fit into
> > >    // a number with 'digits' digits
> > > -  bool fail = false;
> > > -  FIXED_WIDE_INT(128) i
> > > -    = FIXED_WIDE_INT(128)::from (real_to_integer (&value, &fail,
> 128),
> > > SIGNED);
> > >
> > >    // Keep in mind that pure binary types, like BINARY-CHAR, have no
> > > digits
> > >    if( field->data.digits )
> > >      {
> > > -      FIXED_WIDE_INT(128) pow10 = get_power_of_ten
> > (field->data.digits);
> > > -      i = wi::smod_trunc (i, pow10);
> > > +      REAL_VALUE_TYPE pow10 = real_powi10 (field->data.digits);
> > > +      mpfr_t m0, m1;
> > > +
> > > +      mpfr_inits2 (REAL_MODE_FORMAT (TYPE_MODE
> > (float128_type_node))->p,
> > > +            m0, m1, NULL);
> > > +      mpfr_from_real (m0, &value, MPFR_RNDN);
> > > +      mpfr_from_real (m1, &pow10, MPFR_RNDN);
> > > +      mpfr_clear_flags ();
> > > +      mpfr_fmod (m0, m0, m1, MPFR_RNDN);
> > > +      real_from_mpfr (&value, m0,
> > > +               REAL_MODE_FORMAT (TYPE_MODE (float128_type_node)),
> > > +               MPFR_RNDN);
> > > +      real_convert (&value, TYPE_MODE (float128_type_node),
&value);
> > > +      mpfr_clears (m0, m1, NULL);
> > >      }
> > >
> > > +  real_roundeven (&value, TYPE_MODE (float128_type_node), &value);
> > > +
> > > +  bool fail = false;
> > > +  FIXED_WIDE_INT(128) i
> > > +    = FIXED_WIDE_INT(128)::from (real_to_integer (&value, &fail,
> 128),
> > > SIGNED);
> > > +
> > >    /* ???  Use native_encode_* below.  */
> > >    retval = (char *)xmalloc(field->data.capacity);
> > >    switch(field->data.capacity)
> > > @@ -15349,13 +15364,26 @@ digits_from_float128(char *retval, cbl_f
> > >      }
> > >    // We need to make sure that the resulting string will fit into
> > >    // a number with 'digits' digits
> > > +  REAL_VALUE_TYPE pow10 = real_powi10 (field->data.digits);
> > > +  mpfr_t m0, m1;
> > > +
> > > +  mpfr_inits2 (FLOAT_MODE_FORMAT (TYPE_MODE
(float128_type_node))->p,
> > m0,
> > > m1,
> > > +        NULL);
> > > +  mpfr_from_real (m0, &value, MPFR_RNDN);
> > > +  mpfr_from_real (m1, &pow10, MPFR_RNDN);
> > > +  mpfr_clear_flags ();
> > > +  mpfr_fmod (m0, m0, m1, MPFR_RNDN);
> > > +  real_from_mpfr (&value, m0,
> > > +           REAL_MODE_FORMAT (TYPE_MODE (float128_type_node)),
> > > +           MPFR_RNDN);
> > > +  real_convert (&value, TYPE_MODE (float128_type_node), &value);
> > > +  mpfr_clears (m0, m1, NULL);
> > > +  real_roundeven (&value, TYPE_MODE (float128_type_node), &value);
> > > +
> > >    bool fail = false;
> > >    FIXED_WIDE_INT(128) i
> > >      = FIXED_WIDE_INT(128)::from (real_to_integer (&value, &fail,
> 128),
> > > SIGNED);
> > >
> > > -  FIXED_WIDE_INT(128) pow10 = get_power_of_ten
(field->data.digits);
> > > -  i = wi::smod_trunc (i, pow10);
> > > -
> > >    // We convert it to a integer string of digits:
> > >    print_dec (i, ach, SIGNED);
> > >
> > >
> > >
> > >   Jakub
> >
> >
> 
> --
> Richard Biener <rguent...@suse.de>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG
Nuernberg)

Reply via email to