Fortran before 2013 only allowed binary-octal-hex values (BOZ literals) in DATA statements; Fortran 2013 extended it to support them also as argument to INT(), REAL() etc. — Additionally, various compilers (including gfortran) support more as (legacy) extension.

Diagnostic: DATA vs. non DATA usage was/is diagnosed with -std=f95 ("Error: Fortran 2003: …"). Using "X" instead of "Z" for hexadecimals was/is diagnosed (accepted: before GCC 10 with -std=legacy, now with -fallow-invalid-boz).

However, GCC 9 and older silently accepted nonstandard use, e.g. "print *, Z'A'" – even with -std=f2003/f2008! Since GCC 10, it is now rejected unless -fallow-invalid-boz is used.

Main issue: While gfortran 10 still documents the BOZ extensions, neither the extension documentation nor the error message nor point to -fallow-invalid-boz – and the release notes is completely silent regarding BOZ.

Hence, I included two patches:

* The WWWDOCS patch now mentions the change in GCC 10.

* The Fortran patch does: (a) Mention 'X' in the flag documentation (as it is not in an invalid context but just an invalid letter). (b) Tweak error message for 'X' to state how to fix it. (c) When both -std=legacy and -fallow-invalid-boz has been used, it no longer prints a warning; for -std=gnu and -std=f... (+ -fallow…) we still do. (d) If -std=legacy has been used without -fallow-invalid-boz, it now suggests to use -fallow…, but only if fixing is not possible.

I hope with this patch, that using the compiler is more user friendly but still giving the intensive to actually fix the legacy code.

Are the two patches OK – for wwwdocs and for the trunk, respectively?

Tobias

diff --git a/htdocs/gcc-10/changes.html b/htdocs/gcc-10/changes.html
index caa9df70..7df5124f 100644
--- a/htdocs/gcc-10/changes.html
+++ b/htdocs/gcc-10/changes.html
@@ -260,6 +260,13 @@ a work-in-progress.</p>
     with <code>-std=legacy</code>.  <code>-Wargument-mismatch</code>
     has been removed.
   </li>
+  <li>
+    Nonstandard use of BOZ literals now requires the
+    <code>-fallow-invalid-boz</code> flag.  Before, some nonstandard
+    use was only accepted with <code>-std=legacy</code> while
+    other nonstandard usage was silently accepted even with
+    <code>-std=f2003</code>.
+  </li>
   <li>
     At any optimization level except<code>-Os</code>, gfortran now
     uses inline packing for arguments instead of calling a library
	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

Reply via email to