Hello Jose,

I agree that it would be preferable to perform the annotation in the
lowering pass.  I am sending a patch that implements what you described,
the only difference being that the negation flag is applied to the
DENOTATION AST node in a68_lower_negate2.  The annotation is then acted
upon in a68_lower_denotation when checking for overflow.
 
James

On Thu, Feb 26, 2026 at 11:49:00PM +0100, Jose E. Marchesi wrote:
> 
> I am thinking, since integral denotations are always positive (-100 is
> the application of the monadic standard - operator to 100) the new error
> makes it impossible to write something like  -2147483648, forcing the
> user to write something like  -2147483647-1 instead.
> 
> This is not very user friendly.
> 
> A possible solution would be to annotate INT_DENOTATION AST nodes that
> are operands of a - operator with a flag, and not emit the error if
> 
> 1) the flag is set,
> 2) the result of negation would be in-range for the mode of the formula,
> 3) the tree INTEGER_CST can actually hold the resulting value
> 
> This way, the vast majority of these -N denotations would be valid.
> 
> The annotation would be done by a68_lower_denotation before lowering the
> operand, or alternatively in some of the parser passes.  Since this
> really is the result of the two's complement used by tree integers, I
> think the first would be preferable.
> 
> WDYT?
> 
> > Hello James.
> >
> > I just installed the patch on your behalf.
> > Thank you!
> >
> >> Signed-off-by: James Bohl <[email protected]>
> >>
> >> gcc/algol68/ChangeLog
> >>
> >>         * a68-low-units.cc (a68_lower_denotation): Add error on
> >>         integral denotation overflow.
> >>
> >> gcc/testsuite/ChangeLog
> >>
> >>         * algol68/compile/error-denotation-1.a68: New test.
> >>         * algol68/compile/error-denotation-2.a68: Likewise.
> >>         * algol68/compile/error-denotation-3.a68: Likewise.
> >>         * algol68/execute/plusab-1.a68: Fixed denotation overflow.
> >> ---
> >>  gcc/algol68/a68-low-units.cc                         | 12 ++++++++++++
> >>  gcc/testsuite/algol68/compile/error-denotation-1.a68 |  4 ++++
> >>  gcc/testsuite/algol68/compile/error-denotation-2.a68 |  6 ++++++
> >>  gcc/testsuite/algol68/compile/error-denotation-3.a68 |  6 ++++++
> >>  gcc/testsuite/algol68/execute/plusab-1.a68           | 10 +++++-----
> >>  5 files changed, 33 insertions(+), 5 deletions(-)
> >>  create mode 100644 gcc/testsuite/algol68/compile/error-denotation-1.a68
> >>  create mode 100644 gcc/testsuite/algol68/compile/error-denotation-2.a68
> >>  create mode 100644 gcc/testsuite/algol68/compile/error-denotation-3.a68
> >>
> >> diff --git a/gcc/algol68/a68-low-units.cc b/gcc/algol68/a68-low-units.cc
> >> index ba0ab5e2382..8257d2dc96c 100644
> >> --- a/gcc/algol68/a68-low-units.cc
> >> +++ b/gcc/algol68/a68-low-units.cc
> >> @@ -41,6 +41,7 @@
> >>  #include "convert.h"
> >>  
> >>  #include "a68.h"
> >> +#include "a68-pretty-print.h"
> >>  
> >>  /* Note that enclosed clauses, which are units, are handled in
> >>     a68-low-clauses.  */
> >> @@ -250,8 +251,19 @@ a68_lower_denotation (NODE_T *p, LOW_CTX_T ctx)
> >>    s = SUB (p);
> >>  
> >>        type = CTYPE (moid);
> >> +      errno = 0;
> >> +#if defined(INT64_T_IS_LONG)
> >>        int64_t val = strtol (NSYMBOL (s), &end, 10);
> >> +#else
> >> +      int64_t val = strtoll (NSYMBOL (s), &end, 10);
> >> +#endif
> >>        gcc_assert (end[0] == '\0');
> >> +      if (errno == ERANGE || val > wi::max_value (type).to_shwi ())
> >> +  {
> >> +    a68_moid_format_token m (moid);
> >> +    a68_error (s, "denotation is too large for %e", &m);
> >> +  }
> >> +
> >>        return build_int_cst (type, val);
> >>      }
> >>    if (moid == M_BITS
> >> diff --git a/gcc/testsuite/algol68/compile/error-denotation-1.a68 
> >> b/gcc/testsuite/algol68/compile/error-denotation-1.a68
> >> new file mode 100644
> >> index 00000000000..f911cc380b8
> >> --- /dev/null
> >> +++ b/gcc/testsuite/algol68/compile/error-denotation-1.a68
> >> @@ -0,0 +1,4 @@
> >> +{ dg-options {-fstropping=supper} }
> >> +begin int i0 := 123456789012345678901234567890; { dg-error "denotation is 
> >> too large for int" }
> >> +      skip
> >> +end
> >> diff --git a/gcc/testsuite/algol68/compile/error-denotation-2.a68 
> >> b/gcc/testsuite/algol68/compile/error-denotation-2.a68
> >> new file mode 100644
> >> index 00000000000..3aa1ef97bae
> >> --- /dev/null
> >> +++ b/gcc/testsuite/algol68/compile/error-denotation-2.a68
> >> @@ -0,0 +1,6 @@
> >> +{ dg-options {-fstropping=supper} }
> >> +{ dg-require-effective-target int32 }
> >> +begin int i0 := 2147483648; { dg-error "denotation is too large for int" }
> >> +      int i1 := 2147483647;
> >> +      skip
> >> +end
> >> diff --git a/gcc/testsuite/algol68/compile/error-denotation-3.a68 
> >> b/gcc/testsuite/algol68/compile/error-denotation-3.a68
> >> new file mode 100644
> >> index 00000000000..ed27dc1c5be
> >> --- /dev/null
> >> +++ b/gcc/testsuite/algol68/compile/error-denotation-3.a68
> >> @@ -0,0 +1,6 @@
> >> +{ dg-options {-fstropping=supper} }
> >> +{ dg-require-effective-target longlong64 }
> >> +begin long long int i0 := long long 9223372036854775808; { dg-error 
> >> "denotation is too large for long long int" }
> >> +      long long int i1 := long long 9223372036854775807;
> >> +      skip
> >> +end
> >> diff --git a/gcc/testsuite/algol68/execute/plusab-1.a68 
> >> b/gcc/testsuite/algol68/execute/plusab-1.a68
> >> index 8de4e97b046..48865f8a1fe 100644
> >> --- a/gcc/testsuite/algol68/execute/plusab-1.a68
> >> +++ b/gcc/testsuite/algol68/execute/plusab-1.a68
> >> @@ -12,11 +12,11 @@ BEGIN BEGIN INT i := 10;
> >>              i PLUSAB SHORT 100;
> >>              ASSERT (i = SHORT 1200)
> >>        END;
> >> -      BEGIN SHORT SHORT INT i := SHORT SHORT 10000;
> >> -            i +:= SHORT SHORT 1000;
> >> -            ASSERT (i = SHORT SHORT 11000);
> >> -            i PLUSAB SHORT SHORT 1000;
> >> -            ASSERT (i = SHORT SHORT 12000)
> >> +      BEGIN SHORT SHORT INT i := SHORT SHORT 100;
> >> +            i +:= SHORT SHORT 10;
> >> +            ASSERT (i = SHORT SHORT 110);
> >> +            i PLUSAB SHORT SHORT 10;
> >> +            ASSERT (i = SHORT SHORT 120)
> >>        END;
> >>  
> >>        BEGIN LONG INT i := LONG 1000;

Reply via email to