diff mbox series

[Fortran] Reject UNSIGNED for COMPLEX

Message ID cb2f2abb-4d8a-4237-80b4-acbdc14b3900@netcologne.de
State New
Headers show
Series [Fortran] Reject UNSIGNED for COMPLEX | expand

Commit Message

Thomas Koenig Nov. 9, 2024, 4:53 p.m. UTC
Hello world,

the attached patch rejects UNSIGNED arguments for the COMPLEX
function, which is an extension.  It also documents CMPLX,
INT and REAL as taking UNSIGNED arguments.

Regression-tested. OK for trunk?

Best regards

	Thomas

gcc/fortran/ChangeLog:

	* check.cc (gfc_check_complex): Reject UNSIGNED.
	* gfortran.texi: Update example program.  Note that
	CMPLX, INT and REAL also take unsigned arguments.
	* intrinsic.texi (CMPLX): Document UNSIGNED.
	(INT): Likewise.
	(REAL): Likewise.

gcc/testsuite/ChangeLog:

	* gfortran.dg/unsigned_41.f90: New test.

Comments

Harald Anlauf Nov. 10, 2024, 8:54 p.m. UTC | #1
Hi Thomas,

the patch is basically fine.

I am wondering if we should create a new helper function that is
the opposite of type_check ("type_cannot_be"), so that we avoid
redundant code at the source level.  It may not be worth it yet,
so your choice.

Furthermore, if you planned to list intrinsics alphabetically,

diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 429d8461f8f..00276b5b45d 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi

this part needs corrected (in my counting, M comes before S):

@@ -2780,6 +2781,7 @@ The following intrinsics take unsigned arguments:
  @item @code{BLE}, @pxref{BLE}
  @item @code{BLT}, @pxref{BLT}
  @item @code{CSHIFT}, @pxref{CSHIFT}
+@item @code{CMPLX}, @pxref{CMPLX}
  @item @code{DIGITS}, @pxref{DIGITS}
  @item @code{DOT_PRODUCT}, @pxref{DOT_PRODUCT}
  @item @code{DSHIFTL}, @pxref{DSHIFTL}

Not being a native speaker, I stumbled over this:

diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index 9d0b752670b..d11d37761d9 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi

@@ -3637,9 +3638,9 @@ Elemental function
  @item @emph{Arguments}:
  @multitable @columnfractions .15 .70
  @item @var{X} @tab The type may be @code{INTEGER}, @code{REAL},
-or @code{COMPLEX}.
+@code{COMPLEX} or @code{UNSIGNED}.
  @item @var{Y} @tab (Optional; only allowed if @var{X} is not
-@code{COMPLEX}.)  May be @code{INTEGER} or @code{REAL}.
+@code{COMPLEX}.)  May be @code{INTEGER}, @code{REAL} or @code{UNSIGNED}.
                    ^^^ Shouldn't one add "The type" before "may be"?

  @item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
  expression indicating the kind parameter of the result.
  @end multitable


OK for mainline after considering the above comments.

Thanks for the patch!

Harald

Am 09.11.24 um 17:53 schrieb Thomas Koenig:
> Hello world,
> 
> the attached patch rejects UNSIGNED arguments for the COMPLEX
> function, which is an extension.  It also documents CMPLX,
> INT and REAL as taking UNSIGNED arguments.
> 
> Regression-tested. OK for trunk?
> 
> Best regards
> 
>      Thomas
> 
> gcc/fortran/ChangeLog:
> 
>      * check.cc (gfc_check_complex): Reject UNSIGNED.
>      * gfortran.texi: Update example program.  Note that
>      CMPLX, INT and REAL also take unsigned arguments.
>      * intrinsic.texi (CMPLX): Document UNSIGNED.
>      (INT): Likewise.
>      (REAL): Likewise.
> 
> gcc/testsuite/ChangeLog:
> 
>      * gfortran.dg/unsigned_41.f90: New test.
Thomas Koenig Nov. 11, 2024, 8:55 a.m. UTC | #2
Am 10.11.24 um 21:54 schrieb Harald Anlauf:
> Hi Thomas,
> 
> the patch is basically fine.
> 
> I am wondering if we should create a new helper function that is
> the opposite of type_check ("type_cannot_be"), so that we avoid
> redundant code at the source level.  It may not be worth it yet,
> so your choice.
> 
> Furthermore, if you planned to list intrinsics alphabetically,
> 
> diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
> index 429d8461f8f..00276b5b45d 100644
> --- a/gcc/fortran/gfortran.texi
> +++ b/gcc/fortran/gfortran.texi
> 
> this part needs corrected (in my counting, M comes before S):
> 
> @@ -2780,6 +2781,7 @@ The following intrinsics take unsigned arguments:
>   @item @code{BLE}, @pxref{BLE}
>   @item @code{BLT}, @pxref{BLT}
>   @item @code{CSHIFT}, @pxref{CSHIFT}
> +@item @code{CMPLX}, @pxref{CMPLX}
>   @item @code{DIGITS}, @pxref{DIGITS}
>   @item @code{DOT_PRODUCT}, @pxref{DOT_PRODUCT}
>   @item @code{DSHIFTL}, @pxref{DSHIFTL}

Fixed, thanks.

> Not being a native speaker, I stumbled over this:
> 
> diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
> index 9d0b752670b..d11d37761d9 100644
> --- a/gcc/fortran/intrinsic.texi
> +++ b/gcc/fortran/intrinsic.texi
> 
> @@ -3637,9 +3638,9 @@ Elemental function
>   @item @emph{Arguments}:
>   @multitable @columnfractions .15 .70
>   @item @var{X} @tab The type may be @code{INTEGER}, @code{REAL},
> -or @code{COMPLEX}.
> +@code{COMPLEX} or @code{UNSIGNED}.
>   @item @var{Y} @tab (Optional; only allowed if @var{X} is not
> -@code{COMPLEX}.)  May be @code{INTEGER} or @code{REAL}.
> +@code{COMPLEX}.)  May be @code{INTEGER}, @code{REAL} or @code{UNSIGNED}.
>                     ^^^ Shouldn't one add "The type" before "may be"?

We don't add an explicit "The type" or similar in other places, so I
didn't change it.

Pushed as r15-5077-gf5851a5b36b7dce02553d419d90f54e321f417a4 .

Thanks for the review!

Best regards

	Thomas
diff mbox series

Patch

diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 2d4af8e7df3..5c7fe342262 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -2606,6 +2606,23 @@  gfc_check_complex (gfc_expr *x, gfc_expr *y)
   if (!boz_args_check (x, y))
     return false;
 
+  /* COMPLEX is an extension, we do not want UNSIGNED there.  */
+  if (x->ts.type == BT_UNSIGNED)
+    {
+      gfc_error ("%qs argument of %qs intrinsic at %L shall not be "
+		 "UNSIGNED", gfc_current_intrinsic_arg[0]->name,
+		 gfc_current_intrinsic, &x->where);
+      return false;
+    }
+
+  if (y->ts.type == BT_UNSIGNED)
+    {
+      gfc_error ("%qs argument of %qs intrinsic at %L shall not be "
+		 "UNSIGNED", gfc_current_intrinsic_arg[1]->name,
+		 gfc_current_intrinsic, &y->where);
+      return false;
+    }
+
   if (x->ts.type == BT_BOZ)
     {
       if (gfc_invalid_boz (G_("BOZ constant at %L cannot appear in the COMPLEX"
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 429d8461f8f..00276b5b45d 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -2750,8 +2750,9 @@  and @code{Z} descriptors, plus unformatted I/O.
 Here is a small, somewhat contrived example of their use:
 @smallexample
 program main
-  unsigned(kind=8) :: v
-  v = huge(v) - 32u_8
+  use iso_fortran_env, only : uint64
+  unsigned(kind=uint64) :: v
+  v = huge(v) - 32u_uint64
   print *,v
 end program main
 @end smallexample
@@ -2780,6 +2781,7 @@  The following intrinsics take unsigned arguments:
 @item @code{BLE}, @pxref{BLE}
 @item @code{BLT}, @pxref{BLT}
 @item @code{CSHIFT}, @pxref{CSHIFT}
+@item @code{CMPLX}, @pxref{CMPLX}
 @item @code{DIGITS}, @pxref{DIGITS}
 @item @code{DOT_PRODUCT}, @pxref{DOT_PRODUCT}
 @item @code{DSHIFTL}, @pxref{DSHIFTL}
@@ -2794,6 +2796,7 @@  The following intrinsics take unsigned arguments:
 @item @code{IBITS}, @pxref{IBITS}
 @item @code{IBSET}, @pxref{IBSET}
 @item @code{IEOR}, @pxref{IEOR}
+@item @code{INT}, @pxref{INT}
 @item @code{IOR}, @pxref{IOR}
 @item @code{IPARITY}, @pxref{IPARITY}
 @item @code{ISHFT}, @pxref{ISHFT}
@@ -2814,6 +2817,7 @@  The following intrinsics take unsigned arguments:
 @item @code{PRODUCT}, @pxref{PRODUCT}
 @item @code{RANDOM_NUMBER}, @pxref{RANDOM_NUMBER}
 @item @code{RANGE}, @pxref{RANGE}
+@item @code{REAL}, @pxref{REAL}
 @item @code{SHIFTA}, @pxref{SHIFTA}
 @item @code{SHIFTL}, @pxref{SHIFTL}
 @item @code{SHIFTR}, @pxref{SHIFTR}
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index 9d0b752670b..d11d37761d9 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -3626,7 +3626,8 @@  component.  If @var{Y} is not present then the imaginary component is set to
 0.0.  If @var{X} is complex then @var{Y} must not be present.
 
 @item @emph{Standard}:
-Fortran 77 and later
+Fortran 77 and later, extension for @code{UNSIGNED} (@pxref{Unsigned
+integers})
 
 @item @emph{Class}:
 Elemental function
@@ -3637,9 +3638,9 @@  Elemental function
 @item @emph{Arguments}:
 @multitable @columnfractions .15 .70
 @item @var{X} @tab The type may be @code{INTEGER}, @code{REAL},
-or @code{COMPLEX}.
+@code{COMPLEX} or @code{UNSIGNED}.
 @item @var{Y} @tab (Optional; only allowed if @var{X} is not
-@code{COMPLEX}.)  May be @code{INTEGER} or @code{REAL}.
+@code{COMPLEX}.)  May be @code{INTEGER}, @code{REAL} or @code{UNSIGNED}.
 @item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
 expression indicating the kind parameter of the result.
 @end multitable
@@ -8355,7 +8356,8 @@  Convert to integer type
 Fortran 77 and later, with boz-literal-constant Fortran 2008 and later.
 
 @item @emph{Class}:
-Elemental function
+Elemental function, extension for @code{UNSIGNED} (@pxref{Unsigned
+integers}).
 
 @item @emph{Syntax}:
 @code{RESULT = INT(A [, KIND))}
@@ -8386,7 +8388,6 @@  If @var{A} is of type @code{COMPLEX}, rule B is applied to the real part of @var
 If @var{A} is of type @code{UNSIGNED} and @math{0 \leq A \leq}
 @code{HUGE(A)}, @code{INT(A) = A}.  Outside that range, the result
 is interpreted using two's complement.
-
 @end table
 
 @item @emph{Example}:
@@ -12287,7 +12288,10 @@  end program test_rank
 and its use is strongly discouraged.
 
 @item @emph{Standard}:
-Fortran 77 and later, with @var{KIND} argument Fortran 90 and later, has GNU extensions
+Fortran 77 and later, with @var{KIND} argument Fortran 90 and later,
+has GNU extensions.  Extension for @code{UNSIGNED} (@pxref{Unsigned
+integers}).
+
 
 @item @emph{Class}:
 Elemental function
@@ -12300,8 +12304,8 @@  Elemental function
 
 @item @emph{Arguments}:
 @multitable @columnfractions .15 .70
-@item @var{A}    @tab Shall be @code{INTEGER}, @code{REAL}, or
-@code{COMPLEX}.
+@item @var{A}    @tab Shall be @code{INTEGER}, @code{REAL},
+@code{COMPLEX} or @code{UNSIGNED}.
 @item @var{KIND} @tab (Optional) A scalar @code{INTEGER} constant
 expression indicating the kind parameter of the result.
 @end multitable
@@ -12313,14 +12317,14 @@  the following rules:
 @table @asis
 @item (A)
 @code{REAL(A)} is converted to a default real type if @var{A} is an 
-integer or real variable.
+integer, real or unsigned variable.
 @item (B)
 @code{REAL(A)} is converted to a real type with the kind type parameter
 of @var{A} if @var{A} is a complex variable.
 @item (C)
 @code{REAL(A, KIND)} is converted to a real type with kind type
-parameter @var{KIND} if @var{A} is a complex, integer, or real
-variable.
+parameter @var{KIND} if @var{A} is a complex, integer, real
+or unsigned variable.
 @end table
 
 @item @emph{Example}:
diff --git a/gcc/testsuite/gfortran.dg/unsigned_41.f90 b/gcc/testsuite/gfortran.dg/unsigned_41.f90
new file mode 100644
index 00000000000..11a5d7b175a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unsigned_41.f90
@@ -0,0 +1,8 @@ 
+! { dg-do compile }
+! { dg-options "-funsigned" }
+program memain
+  unsigned :: a
+  a = 1u
+  print *,complex(1.0,a) !  { dg-error "shall not be UNSIGNED" }
+  print *,complex(a,1.0) !  { dg-error "shall not be UNSIGNED" }
+end program memain