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

Reply via email to