From 89c1cf2695c796aaf9610615e9f1ecd1f2198da1 Mon Sep 17 00:00:00 2001 From: "Steven G. Kargl" Date: Mon, 24 Dec 2018 18:26:25 +0000 Subject: [PATCH] re PR fortran/45513 (BOZ kinds differently handled, F2008: BOZ in bit intrinsics) 2018-12-24 Steven G. Kargl PR fortran/45513 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. 2018-12-24 Steven G. Kargl PR fortran/45513 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. From-SVN: r267415 --- gcc/fortran/ChangeLog | 17 ++++ gcc/fortran/check.c | 90 +++++++++---------- gcc/fortran/intrinsic.c | 15 ++-- gcc/fortran/intrinsic.h | 4 +- gcc/fortran/intrinsic.texi | 91 ++++++++++++-------- gcc/testsuite/ChangeLog | 8 ++ gcc/testsuite/gfortran.dg/graphite/id-26.f03 | 4 +- gcc/testsuite/gfortran.dg/pr81509_1.f90 | 12 +++ gcc/testsuite/gfortran.dg/pr81509_2.f90 | 18 ++++ 9 files changed, 162 insertions(+), 97 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr81509_1.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr81509_2.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a952a8f4948..a93b99ee333 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,20 @@ +2018-12-24 Steven G. Kargl + + PR fortran/45513 + 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. + 2018-12-23 Paul Thomas PR fortran/77703 diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index 43b07132e0e..2f63c3ed2d5 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -2168,6 +2168,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) { @@ -2177,12 +2192,8 @@ gfc_check_dshift (gfc_expr *i, gfc_expr *j, gfc_expr *shift) if (!type_check (j, 1, BT_INTEGER)) return false; - if (i->is_boz && j->is_boz) - { - gfc_error ("% at %L and %' 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; @@ -2482,7 +2493,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; @@ -2490,10 +2501,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; } @@ -2607,26 +2624,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) @@ -2680,27 +2677,6 @@ 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) { @@ -3584,6 +3560,12 @@ gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask) 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; @@ -3593,6 +3575,8 @@ gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask) if (!same_type_check (i, 0, mask, 2)) return false; + if (mask->is_boz) mask->ts.kind = i->ts.kind; + return true; } @@ -6719,6 +6703,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; } diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 0e0e6fe8314..0c934e13dd7 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -2025,8 +2025,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) @@ -2114,8 +2115,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) @@ -2192,8 +2194,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) diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h index fe30e11c100..0ca3f92a73f 100644 --- a/gcc/fortran/intrinsic.h +++ b/gcc/fortran/intrinsic.h @@ -89,17 +89,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 *); diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index 668888bc5c8..8ea04c38391 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -1144,15 +1144,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 @@ -7523,16 +7528,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 @@ -7973,16 +7979,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 @@ -8291,16 +8298,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 @@ -10296,11 +10304,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}: @@ -11125,15 +11134,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 @@ -14639,16 +14653,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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 10b817f2977..138866b98e3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2018-12-24 Steven G. Kargl + + PR fortran/45513 + 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. + 2018-12-24 Steven G. Kargl * gfortran.dg/ieee/ieee_9.f90: XFAIL on arm*-*-gnueabi[hf]. diff --git a/gcc/testsuite/gfortran.dg/graphite/id-26.f03 b/gcc/testsuite/gfortran.dg/graphite/id-26.f03 index b8fa125359b..06aa7acc9d4 100644 --- a/gcc/testsuite/gfortran.dg/graphite/id-26.f03 +++ b/gcc/testsuite/gfortran.dg/graphite/id-26.f03 @@ -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 diff --git a/gcc/testsuite/gfortran.dg/pr81509_1.f90 b/gcc/testsuite/gfortran.dg/pr81509_1.f90 new file mode 100644 index 00000000000..dc21197c3fe --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr81509_1.f90 @@ -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 + diff --git a/gcc/testsuite/gfortran.dg/pr81509_2.f90 b/gcc/testsuite/gfortran.dg/pr81509_2.f90 new file mode 100644 index 00000000000..919cb4e07a5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr81509_2.f90 @@ -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 + -- 2.30.2