This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[PATCH] Fix fortran/81509
- From: Steve Kargl <sgk at troutmask dot apl dot washington dot edu>
- To: fortran at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Wed, 27 Sep 2017 12:36:25 -0700
- Subject: [PATCH] Fix fortran/81509
- Authentication-results: sourceware.org; auth=none
- Reply-to: sgk at troutmask dot apl dot washington dot edu
The attached patch fixes PR fortran/81509.
In short, F2008 now allows boz-literal-constants in IAND, IOR, IEOR,
DSHIFTL, DSHIFTR, and MERGE_BITS. gfortran currently allows BOZ
argument, but she was not enforcing restrictions in F2008. The
attach patch causes gfortran to conform to F2008.
As aside effect, the patch removes a questionable GNU Fortran
extension that allowed arguments to IAND, IOR, and IEOR to have
different kind type parameters. The behavior of this extension
was not documented.
2017-09-27 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/81509
* check.c: Rename function gfc_check_iand to gfc_check_iand_ieor_ior.
* check.c (boz_args_check): New function. Check I and J not both BOZ.
(gfc_check_dshift,gfc_check_iand_ieor_ior, gfc_check_ishft,
gfc_check_and, gfc_check_merge_bits): Use it.
* check.c (gfc_check_iand_ieor_ior): Force conversion of BOZ to kind
type of other agrument. Remove silly GNU extension.
(gfc_check_ieor, gfc_check_ior): Delete now unused functions.
* intrinsic.c (add_functions): Use gfc_check_iand_ieor_ior. Wrap long
line.
* intrinsic.h: Rename gfc_check_iand to gfc_check_iand_ieor_ior.
Delete prototype for bool gfc_check_ieor and gfc_check_ior
* intrinsic.texi: Update documentation for boz-literal-constant.
2017-09-27 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/81509
* gfortran.dg/graphite/id-26.f03: Fix non-conforming use of IAND.
* gfortran.dg/pr81509_1.f90: New test.
* gfortran.dg/pr81509_2.f90: New test.
--
Steve
20170425 https://www.youtube.com/watch?v=VWUpyCsUKR4
20161221 https://www.youtube.com/watch?v=IbCHE-hONow
Index: gcc/fortran/check.c
===================================================================
--- gcc/fortran/check.c (revision 253236)
+++ gcc/fortran/check.c (working copy)
@@ -2101,6 +2101,21 @@ gfc_check_dprod (gfc_expr *x, gfc_expr *y)
}
+static bool
+boz_args_check(gfc_expr *i, gfc_expr *j)
+{
+ if (i->is_boz && j->is_boz)
+ {
+ gfc_error ("Arguments of %qs at %L and %L cannot both be BOZ "
+ "literal constants", gfc_current_intrinsic, &i->where,
+ &j->where);
+ return false;
+
+ }
+ return true;
+}
+
+
bool
gfc_check_dshift (gfc_expr *i, gfc_expr *j, gfc_expr *shift)
{
@@ -2110,12 +2125,8 @@ gfc_check_dshift (gfc_expr *i, gfc_expr *j, gfc_expr *
if (!type_check (j, 1, BT_INTEGER))
return false;
- if (i->is_boz && j->is_boz)
- {
- gfc_error ("%<I%> at %L and %<J%>' at %L cannot both be BOZ literal "
- "constants", &i->where, &j->where);
- return false;
- }
+ if (!boz_args_check (i, j))
+ return false;
if (!i->is_boz && !j->is_boz && !same_type_check (i, 0, j, 1))
return false;
@@ -2361,7 +2372,7 @@ gfc_check_i (gfc_expr *i)
bool
-gfc_check_iand (gfc_expr *i, gfc_expr *j)
+gfc_check_iand_ieor_ior (gfc_expr *i, gfc_expr *j)
{
if (!type_check (i, 0, BT_INTEGER))
return false;
@@ -2369,10 +2380,16 @@ gfc_check_iand (gfc_expr *i, gfc_expr *j)
if (!type_check (j, 1, BT_INTEGER))
return false;
+ if (!boz_args_check (i, j))
+ return false;
+
+ if (i->is_boz) i->ts.kind = j->ts.kind;
+ if (j->is_boz) j->ts.kind = i->ts.kind;
+
if (i->ts.kind != j->ts.kind)
{
- if (!gfc_notify_std (GFC_STD_GNU, "Different type kinds at %L",
- &i->where))
+ gfc_error ("Arguments of %qs have different kind type parameters "
+ "at %L", gfc_current_intrinsic, &i->where);
return false;
}
@@ -2487,26 +2504,6 @@ gfc_check_idnint (gfc_expr *a)
bool
-gfc_check_ieor (gfc_expr *i, gfc_expr *j)
-{
- if (!type_check (i, 0, BT_INTEGER))
- return false;
-
- if (!type_check (j, 1, BT_INTEGER))
- return false;
-
- if (i->ts.kind != j->ts.kind)
- {
- if (!gfc_notify_std (GFC_STD_GNU, "Different type kinds at %L",
- &i->where))
- return false;
- }
-
- return true;
-}
-
-
-bool
gfc_check_index (gfc_expr *string, gfc_expr *substring, gfc_expr *back,
gfc_expr *kind)
{
@@ -2559,28 +2556,7 @@ gfc_check_intconv (gfc_expr *x)
return true;
}
-
bool
-gfc_check_ior (gfc_expr *i, gfc_expr *j)
-{
- if (!type_check (i, 0, BT_INTEGER))
- return false;
-
- if (!type_check (j, 1, BT_INTEGER))
- return false;
-
- if (i->ts.kind != j->ts.kind)
- {
- if (!gfc_notify_std (GFC_STD_GNU, "Different type kinds at %L",
- &i->where))
- return false;
- }
-
- return true;
-}
-
-
-bool
gfc_check_ishft (gfc_expr *i, gfc_expr *shift)
{
if (!type_check (i, 0, BT_INTEGER)
@@ -3364,6 +3340,12 @@ gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_ex
if (!type_check (j, 1, BT_INTEGER))
return false;
+ if (!boz_args_check (i, j))
+ return false;
+
+ if (i->is_boz) i->ts.kind = j->ts.kind;
+ if (j->is_boz) j->ts.kind = i->ts.kind;
+
if (!type_check (mask, 2, BT_INTEGER))
return false;
@@ -3373,6 +3355,8 @@ gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_ex
if (!same_type_check (i, 0, mask, 2))
return false;
+ if (mask->is_boz) mask->ts.kind = i->ts.kind;
+
return true;
}
@@ -6460,6 +6444,12 @@ gfc_check_and (gfc_expr *i, gfc_expr *j)
if (!scalar_check (j, 1))
return false;
+
+ if (!boz_args_check (i, j))
+ return false;
+
+ if (i->is_boz) i->ts.kind = j->ts.kind;
+ if (j->is_boz) j->ts.kind = i->ts.kind;
return true;
}
Index: gcc/fortran/intrinsic.c
===================================================================
--- gcc/fortran/intrinsic.c (revision 253236)
+++ gcc/fortran/intrinsic.c (working copy)
@@ -1970,8 +1970,9 @@ add_functions (void)
make_generic ("iachar", GFC_ISYM_IACHAR, GFC_STD_F95);
- add_sym_2 ("iand", GFC_ISYM_IAND, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
- gfc_check_iand, gfc_simplify_iand, gfc_resolve_iand,
+ add_sym_2 ("iand", GFC_ISYM_IAND, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_F95,
+ gfc_check_iand_ieor_ior, gfc_simplify_iand, gfc_resolve_iand,
i, BT_INTEGER, di, REQUIRED, j, BT_INTEGER, di, REQUIRED);
if (flag_dec_intrinsic_ints)
@@ -2059,8 +2060,9 @@ add_functions (void)
make_generic ("ichar", GFC_ISYM_ICHAR, GFC_STD_F77);
- add_sym_2 ("ieor", GFC_ISYM_IEOR, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
- gfc_check_ieor, gfc_simplify_ieor, gfc_resolve_ieor,
+ add_sym_2 ("ieor", GFC_ISYM_IEOR, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_F95,
+ gfc_check_iand_ieor_ior, gfc_simplify_ieor, gfc_resolve_ieor,
i, BT_INTEGER, di, REQUIRED, j, BT_INTEGER, di, REQUIRED);
if (flag_dec_intrinsic_ints)
@@ -2137,8 +2139,9 @@ add_functions (void)
make_generic ("long", GFC_ISYM_LONG, GFC_STD_GNU);
- add_sym_2 ("ior", GFC_ISYM_IOR, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
- gfc_check_ior, gfc_simplify_ior, gfc_resolve_ior,
+ add_sym_2 ("ior", GFC_ISYM_IOR, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_F95,
+ gfc_check_iand_ieor_ior, gfc_simplify_ior, gfc_resolve_ior,
i, BT_INTEGER, di, REQUIRED, j, BT_INTEGER, di, REQUIRED);
if (flag_dec_intrinsic_ints)
Index: gcc/fortran/intrinsic.h
===================================================================
--- gcc/fortran/intrinsic.h (revision 253236)
+++ gcc/fortran/intrinsic.h (working copy)
@@ -87,17 +87,15 @@ bool gfc_check_hostnm (gfc_expr *);
bool gfc_check_huge (gfc_expr *);
bool gfc_check_hypot (gfc_expr *, gfc_expr *);
bool gfc_check_i (gfc_expr *);
-bool gfc_check_iand (gfc_expr *, gfc_expr *);
+bool gfc_check_iand_ieor_ior (gfc_expr *, gfc_expr *);
bool gfc_check_and (gfc_expr *, gfc_expr *);
bool gfc_check_ibits (gfc_expr *, gfc_expr *, gfc_expr *);
bool gfc_check_ichar_iachar (gfc_expr *, gfc_expr *);
bool gfc_check_idnint (gfc_expr *);
-bool gfc_check_ieor (gfc_expr *, gfc_expr *);
bool gfc_check_image_status (gfc_expr *, gfc_expr *);
bool gfc_check_index (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
bool gfc_check_int (gfc_expr *, gfc_expr *);
bool gfc_check_intconv (gfc_expr *);
-bool gfc_check_ior (gfc_expr *, gfc_expr *);
bool gfc_check_irand (gfc_expr *);
bool gfc_check_isatty (gfc_expr *);
bool gfc_check_isnan (gfc_expr *);
Index: gcc/fortran/intrinsic.texi
===================================================================
--- gcc/fortran/intrinsic.texi (revision 253236)
+++ gcc/fortran/intrinsic.texi (working copy)
@@ -1142,15 +1142,20 @@ Function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{I} @tab The type shall be either a scalar @code{INTEGER}
-type or a scalar @code{LOGICAL} type.
-@item @var{J} @tab The type shall be the same as the type of @var{I}.
+type or a scalar @code{LOGICAL} type or a boz-literal-constant.
+@item @var{J} @tab The type shall be the same as the type of @var{I} or
+a boz-literal-constant. @var{I} and @var{J} shall not both be
+boz-literal-constants. If either @var{I} or @var{J} is a
+boz-literal-constant, then the other argument must be a scalar @code{INTEGER}.
@end multitable
@item @emph{Return value}:
The return type is either a scalar @code{INTEGER} or a scalar
@code{LOGICAL}. If the kind type parameters differ, then the
smaller kind type is implicitly converted to larger kind, and the
-return has the larger kind.
+return has the larger kind. A boz-literal-constant is
+converted to an @code{INTEGER} with the kind type parameter of
+the other argument as-if a call to @ref{INT} occurred.
@item @emph{Example}:
@smallexample
@@ -7461,16 +7466,17 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{I} @tab The type shall be @code{INTEGER}.
-@item @var{J} @tab The type shall be @code{INTEGER}, of the same
-kind as @var{I}. (As a GNU extension, different kinds are also
-permitted.)
+@item @var{I} @tab The type shall be @code{INTEGER} or a boz-literal-constant.
+@item @var{J} @tab The type shall be @code{INTEGER} with the same
+kind type parameter as @var{I} or a boz-literal-constant.
+@var{I} and @var{J} shall not both be boz-literal-constants.
@end multitable
@item @emph{Return value}:
-The return type is @code{INTEGER}, of the same kind as the
-arguments. (If the argument kinds differ, it is of the same kind as
-the larger argument.)
+The return type is @code{INTEGER} with the kind type parameter of the
+arguments.
+A boz-literal-constant is converted to an @code{INTEGER} with the kind
+type parameter of the other argument as-if a call to @ref{INT} occurred.
@item @emph{Example}:
@smallexample
@@ -7911,16 +7917,17 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{I} @tab The type shall be @code{INTEGER}.
-@item @var{J} @tab The type shall be @code{INTEGER}, of the same
-kind as @var{I}. (As a GNU extension, different kinds are also
-permitted.)
+@item @var{I} @tab The type shall be @code{INTEGER} or a boz-literal-constant.
+@item @var{J} @tab The type shall be @code{INTEGER} with the same
+kind type parameter as @var{I} or a boz-literal-constant.
+@var{I} and @var{J} shall not both be boz-literal-constants.
@end multitable
@item @emph{Return value}:
-The return type is @code{INTEGER}, of the same kind as the
-arguments. (If the argument kinds differ, it is of the same kind as
-the larger argument.)
+The return type is @code{INTEGER} with the kind type parameter of the
+arguments.
+A boz-literal-constant is converted to an @code{INTEGER} with the kind
+type parameter of the other argument as-if a call to @ref{INT} occurred.
@item @emph{Specific names}:
@multitable @columnfractions .20 .20 .20 .25
@@ -8229,16 +8236,17 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{I} @tab The type shall be @code{INTEGER}.
-@item @var{J} @tab The type shall be @code{INTEGER}, of the same
-kind as @var{I}. (As a GNU extension, different kinds are also
-permitted.)
+@item @var{I} @tab The type shall be @code{INTEGER} or a boz-literal-constant.
+@item @var{J} @tab The type shall be @code{INTEGER} with the same
+kind type parameter as @var{I} or a boz-literal-constant.
+@var{I} and @var{J} shall not both be boz-literal-constants.
@end multitable
@item @emph{Return value}:
-The return type is @code{INTEGER}, of the same kind as the
-arguments. (If the argument kinds differ, it is of the same kind as
-the larger argument.)
+The return type is @code{INTEGER} with the kind type parameter of the
+arguments.
+A boz-literal-constant is converted to an @code{INTEGER} with the kind
+type parameter of the other argument as-if a call to @ref{INT} occurred.
@item @emph{Specific names}:
@multitable @columnfractions .20 .20 .20 .25
@@ -10225,11 +10233,12 @@ Elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{I} @tab Shall be of type @code{INTEGER}.
-@item @var{J} @tab Shall be of type @code{INTEGER} and of the same
-kind as @var{I}.
-@item @var{MASK} @tab Shall be of type @code{INTEGER} and of the same
-kind as @var{I}.
+@item @var{I} @tab Shall be of type @code{INTEGER} or a boz-literal-constant.
+@item @var{J} @tab Shall be of type @code{INTEGER} with the same
+kind type parameter as @var{I} or a boz-literal-constant.
+@var{I} and @var{J} shall not both be boz-literal-constants.
+@item @var{MASK} @tab Shall be of type @code{INTEGER} or a boz-literal-constant
+and of the same kind as @var{I}.
@end multitable
@item @emph{Return value}:
@@ -11046,15 +11055,20 @@ Function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{I} @tab The type shall be either a scalar @code{INTEGER}
-type or a scalar @code{LOGICAL} type.
-@item @var{J} @tab The type shall be the same as the type of @var{J}.
+type or a scalar @code{LOGICAL} type or a boz-literal-constant.
+@item @var{J} @tab The type shall be the same as the type of @var{I} or
+a boz-literal-constant. @var{I} and @var{J} shall not both be
+boz-literal-constants. If either @var{I} and @var{J} is a
+boz-literal-constant, then the other argument must be a scalar @code{INTEGER}.
@end multitable
@item @emph{Return value}:
The return type is either a scalar @code{INTEGER} or a scalar
@code{LOGICAL}. If the kind type parameters differ, then the
smaller kind type is implicitly converted to larger kind, and the
-return has the larger kind.
+return has the larger kind. A boz-literal-constant is
+converted to an @code{INTEGER} with the kind type parameter of
+the other argument as-if a call to @ref{INT} occurred.
@item @emph{Example}:
@smallexample
@@ -14506,16 +14520,21 @@ Function
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{I} @tab The type shall be either a scalar @code{INTEGER}
-type or a scalar @code{LOGICAL} type.
-@item @var{J} @tab The type shall be the same as the type of @var{I}.
+@item @var{I} @tab The type shall be either a scalar @code{INTEGER}
+type or a scalar @code{LOGICAL} type or a boz-literal-constant.
+@item @var{J} @tab The type shall be the same as the type of @var{I} or
+a boz-literal-constant. @var{I} and @var{J} shall not both be
+boz-literal-constants. If either @var{I} and @var{J} is a
+boz-literal-constant, then the other argument must be a scalar @code{INTEGER}.
@end multitable
@item @emph{Return value}:
The return type is either a scalar @code{INTEGER} or a scalar
@code{LOGICAL}. If the kind type parameters differ, then the
smaller kind type is implicitly converted to larger kind, and the
-return has the larger kind.
+return has the larger kind. A boz-literal-constant is
+converted to an @code{INTEGER} with the kind type parameter of
+the other argument as-if a call to @ref{INT} occurred.
@item @emph{Example}:
@smallexample
Index: gcc/testsuite/gfortran.dg/graphite/id-26.f03
===================================================================
--- gcc/testsuite/gfortran.dg/graphite/id-26.f03 (revision 253236)
+++ gcc/testsuite/gfortran.dg/graphite/id-26.f03 (working copy)
@@ -51,11 +51,11 @@
! Attempt to create 64-byte aligned allocatable
do i = 1, 64
allocate (c(1023 + i))
- if (iand (loc (c(1)), 63) == 0) exit
+ if (iand(int(loc(c(1)), 8), 63_8) == 0) exit
deallocate (c)
allocate (b(i)%a(1023 + i))
allocate (c(1023 + i))
- if (iand (loc (c(1)), 63) == 0) exit
+ if (iand(int(loc(c(1)), 8), 63_8) == 0) exit
deallocate (c)
end do
if (allocated (c)) then
Index: gcc/testsuite/gfortran.dg/pr81509_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr81509_1.f90 (nonexistent)
+++ gcc/testsuite/gfortran.dg/pr81509_1.f90 (working copy)
@@ -0,0 +1,12 @@
+! { dg-do run }
+! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81509
+program foo
+logical :: a = .false.
+integer :: i = 42
+integer(8) :: k = 42
+if (kind(ieor(z'ade',i)) /= 4) call abort
+if (kind(ior(i,z'1111')) /= 4) call abort
+if (kind(ior(1_8,k)) /= 8) call abort
+if (kind(iand(k,b'1111')) /= 8) call abort
+end program foo
+
Index: gcc/testsuite/gfortran.dg/pr81509_2.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr81509_2.f90 (nonexistent)
+++ gcc/testsuite/gfortran.dg/pr81509_2.f90 (working copy)
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81509
+!
+program foo
+logical :: a = .false.
+integer :: i = 42
+integer(8) :: k
+k = iand(z'aaaa', z'1234') ! { dg-error "cannot both be BOZ literal" }
+k = and(z'aaaa', z'1234') ! { dg-error "cannot both be BOZ literal" }
+k = and(1, z'1234')
+k = and(i, z'1234')
+k = ieor(z'ade',i)
+k = ior(i,z'1111')
+k = ior(i,k) ! { dg-error "different kind type parameters" }
+k = and(i,k)
+k = and(a,z'1234') ! { dg-error "must have the same type" }
+end program foo
+