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;
