PR fortran/93253 * check.c (gfc_invalid_boz): With -std=legacy, suggest the new -fallow-invalid-boz flag. With -std=legacy and that flag, no longer warn. * gfortran.texi (BOZ literal constants): List another missing extension and refer to -fallow-invalid-boz. * lang.opt (fallow-invalid-boz): Also mention 'X' in the help text as it is not covered by the previous wording. * primary.c (match_boz_constant): Tweak wording such that it is clear how to fix the nonstandard use. PR fortran/93253 * fortran.dg/boz_7.f90: Updated dg-error. diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index c7f0187b377..f03764abaef 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -56,18 +56,30 @@ reset_boz (gfc_expr *x) gfc_invalid_boz() is a helper function to simplify error/warning generation. gfortran accepts the nonstandard 'X' for 'Z', and gfortran allows the BOZ indicator to appear as a suffix. If -fallow-invalid-boz - is used, then issue a warning; otherwise issue an error. */ + is used, then issue a warning (unless -std=legacy); otherwise issue an + error. */ bool gfc_invalid_boz (const char *msg, locus *loc) { if (flag_allow_invalid_boz) { - gfc_warning (0, msg, loc); + if (gfc_option.warn_std & GFC_STD_LEGACY) + gfc_warning (0, msg, loc); return false; } - gfc_error (msg, loc); + if (!(gfc_option.warn_std & GFC_STD_LEGACY)) + { + const char hint[] = ". Use %<-fallow-invalid-boz%> if you cannot fix it"; + size_t len = strlen (msg) + strlen (hint) + 1; + char *msg2 = (char *) alloca (len); + strcpy (msg2, msg); + strcat (msg2, hint); + gfc_error (msg2, loc); + } + else + gfc_error (msg, loc); return true; } diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 4cf8b3a5c24..98fc74f3e67 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -1863,9 +1863,11 @@ Fortran standard states that the treatment of the sign bit is processor dependent. Gfortran interprets the sign bit as a user would expect. As a deprecated extension, GNU Fortran allows hexadecimal BOZ literal -constants to be specified using the @code{X} prefix. The BOZ literal +constants to be specified using the @code{X} prefix. That the BOZ literal constant can also be specified by adding a suffix to the string, for -example, @code{Z'ABC'} and @code{'ABC'X} are equivalent. +example, @code{Z'ABC'} and @code{'ABC'X} are equivalent. And BOZ literals +outside @code{DATA} and the intrinsic functions listed in the Fortran +standard. Use @option{-fallow-invalid-boz} to enable the extension. @node Real array indices @subsection Real array indices diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 3858331bcc0..59523f74acf 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -387,7 +387,7 @@ All intrinsics procedures are available regardless of selected standard. fallow-invalid-boz Fortran RejectNegative Var(flag_allow_invalid_boz) -Allow a BOZ literal constant to appear in an invalid context. +Allow a BOZ literal constant to appear in an invalid context and with X instead of Z. fallow-leading-underscore Fortran Undocumented Var(flag_allow_leading_underscore) diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index e2b6fcb2106..07b8ac08ba2 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -433,7 +433,7 @@ match_boz_constant (gfc_expr **result) if (x_hex && gfc_invalid_boz ("Hexadecimal constant at %L uses " - "nonstandard syntax", &gfc_current_locus)) + "nonstandard X instead of Z", &gfc_current_locus)) return MATCH_ERROR; old_loc = gfc_current_locus; diff --git a/gcc/testsuite/gfortran.dg/boz_7.f90 b/gcc/testsuite/gfortran.dg/boz_7.f90 index 45fa7a7df19..d2a51ac03e2 100644 --- a/gcc/testsuite/gfortran.dg/boz_7.f90 +++ b/gcc/testsuite/gfortran.dg/boz_7.f90 @@ -7,6 +7,6 @@ ! integer :: k, m integer :: j = z'000abc' ! { dg-error "BOZ used outside a DATA statement" } -data k/x'0003'/ ! { dg-error "nonstandard syntax" } +data k/x'0003'/ ! { dg-error "nonstandard X instead of Z" } data m/'0003'z/ ! { dg-error "nonstandard postfix" } end