Hi James.
Looks good, but I think you need to initialize NEGATED to false in
a68-parser.cc:a68_new_node.
Also please make sure to use tabs in the changelog entries in the commit
message, like in:
* a68-low-prelude.cc (a68_lower_negate2): Annotate denotation
as being negated.
* a68-low-units.cc (a68_lower_denotation): Allow the full range
of negative values if the denotation is negated.
* a68-types.h (struct NODE_T): Add negated field.
(NEGATED): Define.
You can check particular commits with
contrib/gcc-changelog/git_check_commit.py.
> Signed-off-by: James Bohl <[email protected]>
>
> gcc/algol68/ChangeLog
>
> * a68-low-prelude.cc (a68_lower_negate2): Annotate denotation
> as being negated.
> * a68-low-units.cc (a68_lower_denotation): Allow the full range
> of negative values if the denotation is negated.
> * a68-types.h (struct NODE_T): Add negated field.
> (NEGATED): Define.
>
> gcc/testsuite/ChangeLog
>
> * algol68/compile/error-denotation-2.a68: Check for no error on
> minimum negative value.
> * algol68/compile/error-denotation-3.a68: Likewise.
> ---
> gcc/algol68/a68-low-prelude.cc | 9 +++++++++
> gcc/algol68/a68-low-units.cc | 10 +++++++---
> gcc/algol68/a68-types.h | 6 +++++-
> gcc/testsuite/algol68/compile/error-denotation-2.a68 | 1 +
> gcc/testsuite/algol68/compile/error-denotation-3.a68 | 1 +
> 5 files changed, 23 insertions(+), 4 deletions(-)
>
> diff --git a/gcc/algol68/a68-low-prelude.cc b/gcc/algol68/a68-low-prelude.cc
> index 8b9d973327f..7fdac27f3a2 100644
> --- a/gcc/algol68/a68-low-prelude.cc
> +++ b/gcc/algol68/a68-low-prelude.cc
> @@ -90,6 +90,15 @@ a68_lower_confirm2 (NODE_T *p, LOW_CTX_T ctx)
> tree
> a68_lower_negate2 (NODE_T *p, LOW_CTX_T ctx)
> {
> + /* Annotate denotations as being negated. */
> + NODE_T *s = NEXT (SUB (p));
> + if (ATTRIBUTE (s) == SECONDARY
> + && ATTRIBUTE (SUB (s)) == PRIMARY
> + && ATTRIBUTE (SUB (SUB (s))) == DENOTATION)
> + {
> + NEGATED (SUB (SUB (s))) = true;
> + }
> +
> return fold_build1_loc (a68_get_node_location (p),
> NEGATE_EXPR,
> CTYPE (MOID (p)),
> diff --git a/gcc/algol68/a68-low-units.cc b/gcc/algol68/a68-low-units.cc
> index 8257d2dc96c..86eb68cc141 100644
> --- a/gcc/algol68/a68-low-units.cc
> +++ b/gcc/algol68/a68-low-units.cc
> @@ -253,12 +253,16 @@ a68_lower_denotation (NODE_T *p, LOW_CTX_T ctx)
> type = CTYPE (moid);
> errno = 0;
> #if defined(INT64_T_IS_LONG)
> - int64_t val = strtol (NSYMBOL (s), &end, 10);
> + uint64_t val = strtoul (NSYMBOL (s), &end, 10);
> #else
> - int64_t val = strtoll (NSYMBOL (s), &end, 10);
> + uint64_t val = strtoull (NSYMBOL (s), &end, 10);
> #endif
> gcc_assert (end[0] == '\0');
> - if (errno == ERANGE || val > wi::max_value (type).to_shwi ())
> + uint64_t max_positive = uint64_t (wi::max_value (type).to_shwi ());
> + uint64_t max_negative = -uint64_t (wi::min_value (type).to_shwi ());
> + if (errno == ERANGE
> + || (NEGATED (p) && (val > max_negative))
> + || (!NEGATED (p) && (val > max_positive)))
> {
> a68_moid_format_token m (moid);
> a68_error (s, "denotation is too large for %e", &m);
> diff --git a/gcc/algol68/a68-types.h b/gcc/algol68/a68-types.h
> index ad6b2a92260..9dc3d006e9f 100644
> --- a/gcc/algol68/a68-types.h
> +++ b/gcc/algol68/a68-types.h
> @@ -436,7 +436,9 @@ struct GTY(()) OPTIONS_T
> DEFINING_INDICANT nodes that appear in declarations marked with PUB.
>
> CDECL is a GCC GENERIC tree corresponding to a DECL_FIELD for FIELD
> - nodes. */
> + nodes.
> +
> + NEGATED is used to mark DENOTATION nodes as being negated. */
>
> struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) NODE_T
> {
> @@ -456,6 +458,7 @@ struct GTY((chain_next ("%h.next"), chain_prev
> ("%h.previous"))) NODE_T
> tree cdecl;
> bool dynamic_stack_allocs;
> bool publicized;
> + bool negated;
> };
>
> #define NO_NODE ((NODE_T *) 0)
> @@ -1036,6 +1039,7 @@ struct GTY(()) A68_T
> #define NCOMMENT_CHAR_IN_LINE(p) (COMMENT_CHAR_IN_LINE (INFO (p)))
> #define NCOMMENT_LINE(p) (COMMENT_LINE (INFO (p)))
> #define NCOMMENT_TYPE(p) (COMMENT_TYPE (INFO (p)))
> +#define NEGATED(p) ((p)->negated)
> #define NPRAGMAT(p) (PRAGMAT (INFO (p)))
> #define NPRAGMAT_CHAR_IN_LINE(p) (PRAGMAT_CHAR_IN_LINE (INFO (p)))
> #define NPRAGMAT_LINE(p) (PRAGMAT_LINE (INFO (p)))
> diff --git a/gcc/testsuite/algol68/compile/error-denotation-2.a68
> b/gcc/testsuite/algol68/compile/error-denotation-2.a68
> index 3aa1ef97bae..d295e4e9cce 100644
> --- a/gcc/testsuite/algol68/compile/error-denotation-2.a68
> +++ b/gcc/testsuite/algol68/compile/error-denotation-2.a68
> @@ -2,5 +2,6 @@
> { dg-require-effective-target int32 }
> begin int i0 := 2147483648; { dg-error "denotation is too large for int" }
> int i1 := 2147483647;
> + int i2 := -2147483648;
> skip
> end
> diff --git a/gcc/testsuite/algol68/compile/error-denotation-3.a68
> b/gcc/testsuite/algol68/compile/error-denotation-3.a68
> index ed27dc1c5be..67da411e03c 100644
> --- a/gcc/testsuite/algol68/compile/error-denotation-3.a68
> +++ b/gcc/testsuite/algol68/compile/error-denotation-3.a68
> @@ -2,5 +2,6 @@
> { 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;
> + long long int i2 := -long long 9223372036854775808;
> skip
> end