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;
