PR fortran/87919 patch for -fno-dec-structure

Message ID 686ba917-27d4-451b-a0de-b28074166f2c@codethink.co.uk
State New
Headers show
Series
  • PR fortran/87919 patch for -fno-dec-structure
Related show

Commit Message

Mark Eggleston Nov. 7, 2018, 3:07 p.m.
Please find attached the patch and a ChangeLog entry. This is my first 
patch, apologies for any mistakes in the submission process.

This patch is the simple removal of an OPT_dec_structure case from a 
switch statement, it was noticeable as there was no corresponding code 
for the other dec specific options. I spotted this before the creation 
of PR fortran/87919 so I now know that this fixes the broken behaviour 
of -fno-dec-structure.

The patch contains a change to gcc/fortran/options.c and four testcases 
pr87919-dec-structure-*.f where * is one of 1, 2, 3 and 4.

The testcases are specified to compile with no specific options, -fdec, 
-fdec-structure and both -fdec and -fno-dec-structure.

After building the compiler on x86_64 I got the following results 
aggregated from make -j 5 check-fortran:

         === gfortran Summary ===

# of expected passes        48184
# of expected failures        103
# of unsupported tests        79

Comments

Jakub Jelinek Nov. 7, 2018, 3:22 p.m. | #1
On Wed, Nov 07, 2018 at 03:07:04PM +0000, Mark Eggleston wrote:

> 	PR fortran/87919
> 	* options.c (gfc_handle_option): Removed case OPT_fdec_structure
> 	as it breaks the handling of -fno-dec-structure.

No entries for the tests, i.e.
	* gfortran.dg/pr87919-dec-structure-1.f: New test.
	* gfortran.dg/pr87919-dec-structure-2.f: New test.
	* gfortran.dg/pr87919-dec-structure-3.f: New test.
	* gfortran.dg/pr87919-dec-structure-4.f: New test.

> diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
> index 73f5389361d9..3b7c2d40fe8a 100644
> --- a/gcc/fortran/options.c
> +++ b/gcc/fortran/options.c
> @@ -761,10 +761,6 @@ gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
>        /* Enable all DEC extensions.  */
>        set_dec_flags (1);
>        break;
> -
> -    case OPT_fdec_structure:
> -      flag_dec_structure = 1;
> -      break;
>      }
>  
>    Fortran_handle_option_auto (&global_options, &global_options_set, 

LGTM, but I'll defer the final review to Fortran maintainers.

> diff --git a/gcc/testsuite/gfortran.dg/pr87919-dec-structure-1.f b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-1.f
> new file mode 100644
> index 000000000000..4dd34082b97a
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-1.f
> @@ -0,0 +1,21 @@
> +! { dg-do compile }
> +!
> +! PR/fortran/87919

Without the first /, i.e.
! PR fortran/87919
(in all tests).

> +++ b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-2.f
> @@ -0,0 +1,22 @@
> +! { dg-do run }
> +! { dg-options "-fdec" }
> +!
> +! PR/fortran/87919
> +!
> +! Should compile anf run with the -fdec option

s/anf/and/ (in several tests).

> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-3.f
> @@ -0,0 +1,22 @@
> +! { dg-do run }
> +! { dg-options "-fdec-structure" }
> +!
> +! PR/fortran/87919
> +!
> +! Should compile anf run with the -fdec option

s/-fdec/-fdec-structure/ in this case.

> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-4.f
> @@ -0,0 +1,22 @@
> +! { dg-do compile }
> +! { dg-options "-fdec -fno-dec-structure" }
> +!
> +! PR/fortran/87919
> +!
> +! Should fail to compile with the -fdec and -fno-dec-structure option

s/option/options/

I'd suggest to add another test, with
! { dg-options "-fdec-structure -fno-dec-structure" }
where the options cancel each other and the result is no DEC structure
support.

	Jakub
Fritz Reese Nov. 7, 2018, 10:05 p.m. | #2
On 11/7/18, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Nov 07, 2018 at 03:07:04PM +0000, Mark Eggleston wrote:
>
>>      PR fortran/87919
>>      * options.c (gfc_handle_option): Removed case OPT_fdec_structure
>>      as it breaks the handling of -fno-dec-structure.
>
> No entries for the tests, i.e.
>       * gfortran.dg/pr87919-dec-structure-1.f: New test.
>       * gfortran.dg/pr87919-dec-structure-2.f: New test.
>       * gfortran.dg/pr87919-dec-structure-3.f: New test.
>       * gfortran.dg/pr87919-dec-structure-4.f: New test.
>
>> diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
>> index 73f5389361d9..3b7c2d40fe8a 100644
>> --- a/gcc/fortran/options.c
>> +++ b/gcc/fortran/options.c
>> @@ -761,10 +761,6 @@ gfc_handle_option (size_t scode, const char *arg,
>> HOST_WIDE_INT value,
>>        /* Enable all DEC extensions.  */
>>        set_dec_flags (1);
>>        break;
>> -
>> -    case OPT_fdec_structure:
>> -      flag_dec_structure = 1;
>> -      break;
>>      }
>>
>>    Fortran_handle_option_auto (&global_options, &global_options_set,
>
> LGTM, but I'll defer the final review to Fortran maintainers.

Thanks for the patch Mark, I concur with Jakub that it is correct for
what it does. However, I have a few comments in addition to the fixes
recommended by Jakub regarding the test cases.

First, I would prefer to name these test cases as "dec_structure_*.f"
to align with the other (23) -fdec-structure test cases. Second, the
third case (*dec-structure-3.f) is unnecessary because it is identical
in function to dec_structure_1.f90. I concur with the remaining test
cases, as well as Jakub's suggestion to cover "-fdec-structure
-fno-dec-structure" with an additional test. I would name the final
four (= 4 - 1 + 1) tests as "dec_structure_[24-27].f".


I have taken the liberty of extending this patch to cover the
remainder of PR 87919. That is, to fix -fno-* for -fno-dec,
-fno-check-array-temporaries and -fno-init-local-zero. In the extended
patch, the 'value' set for the aforementioned options is no longer
ignored, so that value=1 truly means set and value=0 truly means
"unset". Previously, the aforementioned flags effectively ignored the
value=0 condition. Similarly to the tests Mark provided with
-fdec-structure, I've provided new tests for the various facets of
-fno-dec, -fno-check-array-temporaries, and -fno-init-local-zero.

Below is the changelog. Bootstraps and regtests fine for me on
x86_64-redhat-linux. If it looks OK I'll commit to trunk (and probably
backport to 8-branch and 7-branch since the affected code appears to
be the same for those branches).


From 2d9e39bbf4a179ae433f33f4e7039b85078ba72f Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Wed, 7 Nov 2018 15:13:50 -0500
Subject: [PATCH] PR fortran/87919

Fix handling -fno-* prefix for init-local-zero, check-array-temporaries and dec.

gcc/fortran/
        * options.c (SET_FLAG, SET_BITFLAG): New macros.
        (set_dec_flags): Unset DEC flags with value==0.
        (set_init_local_zero): New helper for -finit-local-zero flag group.
        (gfc_init_options): Fix disabling of init flags, array temporaries
        check, and dec flags when value is zero (from -fno-*).

gcc/testsuiste/
        * gfortran.dg/array_temporaries_5.f90: New test.
        * gfortran.dg/dec_bitwise_ops_3.f90: Ditto.
        * gfortran.dg/dec_d_lines_3.f: Ditto.
        * gfortran.dg/dec_exp_4.f90: Ditto.
        * gfortran.dg/dec_exp_5.f90: Ditto.
        * gfortran.dg/dec_io_7.f90: Ditto.
        * gfortran.dg/dec_structure_24.f: Ditto.
        * gfortran.dg/dec_structure_25.f: Ditto.
        * gfortran.dg/dec_structure_26.f: Ditto.
        * gfortran.dg/dec_structure_27.f: Ditto.
        * gfortran.dg/dec_type_print_3.f90: Ditto.
        * gfortran.dg/init_flag_20.f90: Ditto.
---
 gcc/fortran/options.c                             | 70 +++++++++++++++--------
 gcc/testsuite/gfortran.dg/array_temporaries_5.f90 | 20 +++++++
 gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90   | 19 ++++++
 gcc/testsuite/gfortran.dg/dec_d_lines_3.f         | 10 ++++
 gcc/testsuite/gfortran.dg/dec_exp_4.f90           | 13 +++++
 gcc/testsuite/gfortran.dg/dec_exp_5.f90           | 15 +++++
 gcc/testsuite/gfortran.dg/dec_io_7.f90            | 22 +++++++
 gcc/testsuite/gfortran.dg/dec_structure_24.f      | 21 +++++++
 gcc/testsuite/gfortran.dg/dec_structure_25.f      | 22 +++++++
 gcc/testsuite/gfortran.dg/dec_structure_26.f      | 22 +++++++
 gcc/testsuite/gfortran.dg/dec_structure_27.f      | 20 +++++++
 gcc/testsuite/gfortran.dg/dec_type_print_3.f90    | 29 ++++++++++
 gcc/testsuite/gfortran.dg/init_flag_20.f90        | 62 ++++++++++++++++++++
 13 files changed, 320 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/array_temporaries_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_d_lines_3.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_exp_4.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_exp_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_io_7.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_24.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_25.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_26.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_27.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_type_print_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/init_flag_20.f90
Jakub Jelinek Nov. 7, 2018, 10:32 p.m. | #3
On Wed, Nov 07, 2018 at 05:05:13PM -0500, Fritz Reese wrote:

--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -32,6 +32,20 @@ along with GCC; see the file COPYING3.  If not see
 
 gfc_option_t gfc_option;
 
+#define _expand(m) m

I think it would be better to avoid names like _expand, too generic
name and starts with underscore, name it e.g. SET_BITFLAG_1 or something
similar.  And it isn't mentioned in the ChangeLog.

@@ -62,14 +75,30 @@ set_dec_flags (int value)
     }

What about the
      /* Allow legacy code without warnings.  */
      gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
        | GFC_STD_GNU | GFC_STD_LEGACY;
      gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
that is done for value, shouldn't set_dec_flags remove those
flags again?  Maybe not the allow_std ones, because those are set already by
default, perhaps just the warn_std flags?

   /* Set other DEC compatibility extensions.  */
-  flag_dollar_ok |= value;
-  flag_cray_pointer |= value;
-  flag_dec_structure |= value;
-  flag_dec_intrinsic_ints |= value;
-  flag_dec_static |= value;
-  flag_dec_math |= value;
+  SET_BITFLAG (flag_dollar_ok, value, value);
+  SET_BITFLAG (flag_cray_pointer, value, value);
+  SET_BITFLAG (flag_dec_structure, value, value);
+  SET_BITFLAG (flag_dec_intrinsic_ints, value, value);
+  SET_BITFLAG (flag_dec_static, value, value);
+  SET_BITFLAG (flag_dec_math, value, value);
 }
 
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+! { dg-options "-fcheck-array-temporaries -fno-check-array-temporaries" }
+!
+! PR fortran/87919
+!
+! Ensure -fno-check-array-temporaries disables array temporary checking.
+! Copied from array_temporaries_2.f90.

For tests where you expect no errors and that are just copies of other
testcases, perhaps
include 'array_temporaries_2.f90'
or similar instead?

	Jakub
Fritz Reese Nov. 8, 2018, 5:09 p.m. | #4
On Wed, Nov 7, 2018 at 5:32 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Wed, Nov 07, 2018 at 05:05:13PM -0500, Fritz Reese wrote:
>
> --- a/gcc/fortran/options.c
> +++ b/gcc/fortran/options.c
> @@ -32,6 +32,20 @@ along with GCC; see the file COPYING3.  If not see
>
>  gfc_option_t gfc_option;
>
> +#define _expand(m) m
>
> I think it would be better to avoid names like _expand, too generic
> name and starts with underscore, name it e.g. SET_BITFLAG_1 or something
> similar.  And it isn't mentioned in the ChangeLog.

I find "expand" a more helpful name than "set_bitflag_1" since it
describes what the macro does. However, I don't think it makes too
much of a difference so I'll follow your preference (but I'll use
SET_BITFLAG2 since then the definition line fits in 80 characters).

>
> @@ -62,14 +75,30 @@ set_dec_flags (int value)
>      }
>
> What about the
>       /* Allow legacy code without warnings.  */
>       gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
>         | GFC_STD_GNU | GFC_STD_LEGACY;
>       gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
> that is done for value, shouldn't set_dec_flags remove those
> flags again?  Maybe not the allow_std ones, because those are set already by
> default, perhaps just the warn_std flags?
>

Sure. I wasn't convinced about this and how it might interplay with
-std= so I left it alone, but I suppose it makes sense to unsuppress
the warnings when disabling -fdec.

> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
> @@ -0,0 +1,20 @@
> +! { dg-do run }
> +! { dg-options "-fcheck-array-temporaries -fno-check-array-temporaries" }
> +!
> +! PR fortran/87919
> +!
> +! Ensure -fno-check-array-temporaries disables array temporary checking.
> +! Copied from array_temporaries_2.f90.
>
> For tests where you expect no errors and that are just copies of other
> testcases, perhaps
> include 'array_temporaries_2.f90'
> or similar instead?
>

Strictly speaking it's not an exact copy because it omits the final {
dg-output } check for the runtime warning, since the warning is
supposed to occur in array_temporaries_2.f90 but not in the new case
array_temporaries_5.f90. I assumed include would propagate the {
dg-output } check -- upon actually testing this, it appears that is
not the case. I find this misleading at a glance, but it works, so I
don't mind this with an extra comment line.

Attached is a new patch which incorporates your recommendations.
Here's the diff between the two, followed by the new changelog:

diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index e703cad96fd..167621905bc 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -32,8 +32,6 @@ along with GCC; see the file COPYING3.  If not see

 gfc_option_t gfc_option;

-#define _expand(m) m
-
 #define SET_FLAG(flag, condition, on_value, off_value) \
   do \
     { \
@@ -43,8 +41,10 @@ gfc_option_t gfc_option;
        flag = (off_value); \
     } while (0)

+#define SET_BITFLAG2(m) m
+
 #define SET_BITFLAG(flag, condition, value) \
-  _expand (SET_FLAG (flag, condition, (flag | (value)), (flag & ~(value))))
+  SET_BITFLAG2 (SET_FLAG (flag, condition, (flag | (value)), (flag &
~(value))))


 /* Set flags that control warnings and errors for different
@@ -66,15 +66,17 @@ set_default_std_flags (void)
 static void
 set_dec_flags (int value)
 {
+  /* Allow legacy code without warnings.
+     Nb. We do not unset the allowed standards with value == 0 because
+     they are set by default in set_default_std_flags.  */
   if (value)
-    {
-      /* Allow legacy code without warnings.  */
-      gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
-        | GFC_STD_GNU | GFC_STD_LEGACY;
-      gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
-    }
+    gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
+      | GFC_STD_GNU | GFC_STD_LEGACY;
+
+  SET_BITFLAG (gfc_option.warn_std, !value, GFC_STD_LEGACY);
+  SET_BITFLAG (gfc_option.warn_std, !value, GFC_STD_F95_DEL);

-  /* Set other DEC compatibility extensions.  */
+  /* Set (or unset) other DEC compatibility extensions.  */
   SET_BITFLAG (flag_dollar_ok, value, value);
   SET_BITFLAG (flag_cray_pointer, value, value);
   SET_BITFLAG (flag_dec_structure, value, value);
@@ -855,3 +871,7 @@ gfc_get_option_string (void)
 }

 #undef SET_BITFLAG
+#undef SET_BITFLAG2
 #undef SET_FLAG
-#undef _expand

diff --git a/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
b/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
index 0070a935933..dd147ba38ed 100644
--- a/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
+++ b/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
@@ -4,17 +4,7 @@
 ! PR fortran/87919
 !
 ! Ensure -fno-check-array-temporaries disables array temporary checking.
-! Copied from array_temporaries_2.f90.
 !

-program test
-  implicit none
-  integer :: a(3,3)
-  call foo(a(:,1))  ! OK, no temporary created
-  call foo(a(1,:))  ! BAD, temporary var created
-contains
-  subroutine foo(x)
-    integer :: x(3)
-    x = 5
-  end subroutine foo
-end program test
+! Note that 'include' drops the dg-output check from the original test case.
+include 'array_temporaries_2.f90'



>>>>>> ChangeLog <<<<<<
PR fortran/87919

Fix handling -fno-* prefix for init-local-zero, check-array-temporaries and dec.

gcc/fortran/
        * options.c (SET_FLAG, SET_BITFLAG, SET_BITFLAG2): New macros.
        (set_dec_flags): Set/unset DEC and std flags according to value.
        (set_init_local_zero): New helper for -finit-local-zero flag group.
        (gfc_init_options): Fix disabling of init flags, array temporaries
        check, and dec flags when value is zero (from -fno-*).

gcc/testsuiste/
        * gfortran.dg/array_temporaries_5.f90: New test.
        * gfortran.dg/dec_bitwise_ops_3.f90: Ditto.
        * gfortran.dg/dec_d_lines_3.f: Ditto.
        * gfortran.dg/dec_exp_4.f90: Ditto.
        * gfortran.dg/dec_exp_5.f90: Ditto.
        * gfortran.dg/dec_io_7.f90: Ditto.
        * gfortran.dg/dec_structure_24.f: Ditto.
        * gfortran.dg/dec_structure_25.f: Ditto.
        * gfortran.dg/dec_structure_26.f: Ditto.
        * gfortran.dg/dec_structure_27.f: Ditto.
        * gfortran.dg/dec_type_print_3.f90: Ditto.
        * gfortran.dg/init_flag_20.f90: Ditto.
From 7257d88e050f96f83b66b8313087dbc8934dc465 Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Thu, 8 Nov 2018 11:58:41 -0500
Subject: [PATCH] PR fortran/87919

Fix handling -fno-* prefix for init-local-zero, check-array-temporaries and dec.

gcc/fortran/
	* options.c (SET_FLAG, SET_BITFLAG, SET_BITFLAG2): New macros.
	(set_dec_flags): Set/unset DEC and std flags according to value.
	(set_init_local_zero): New helper for -finit-local-zero flag group.
	(gfc_init_options): Fix disabling of init flags, array temporaries
	check, and dec flags when value is zero (from -fno-*).

gcc/testsuiste/
	* gfortran.dg/array_temporaries_5.f90: New test.
	* gfortran.dg/dec_bitwise_ops_3.f90: Ditto.
	* gfortran.dg/dec_d_lines_3.f: Ditto.
	* gfortran.dg/dec_exp_4.f90: Ditto.
	* gfortran.dg/dec_exp_5.f90: Ditto.
	* gfortran.dg/dec_io_7.f90: Ditto.
	* gfortran.dg/dec_structure_24.f: Ditto.
	* gfortran.dg/dec_structure_25.f: Ditto.
	* gfortran.dg/dec_structure_26.f: Ditto.
	* gfortran.dg/dec_structure_27.f: Ditto.
	* gfortran.dg/dec_type_print_3.f90: Ditto.
	* gfortran.dg/init_flag_20.f90: Ditto.
---
 gcc/fortran/options.c                             | 88 ++++++++++++++---------
 gcc/testsuite/gfortran.dg/array_temporaries_5.f90 | 10 +++
 gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90   | 19 +++++
 gcc/testsuite/gfortran.dg/dec_d_lines_3.f         | 10 +++
 gcc/testsuite/gfortran.dg/dec_exp_4.f90           | 13 ++++
 gcc/testsuite/gfortran.dg/dec_exp_5.f90           | 15 ++++
 gcc/testsuite/gfortran.dg/dec_io_7.f90            | 22 ++++++
 gcc/testsuite/gfortran.dg/dec_structure_24.f      | 21 ++++++
 gcc/testsuite/gfortran.dg/dec_structure_25.f      | 22 ++++++
 gcc/testsuite/gfortran.dg/dec_structure_26.f      | 22 ++++++
 gcc/testsuite/gfortran.dg/dec_structure_27.f      | 20 ++++++
 gcc/testsuite/gfortran.dg/dec_type_print_3.f90    | 29 ++++++++
 gcc/testsuite/gfortran.dg/init_flag_20.f90        | 62 ++++++++++++++++
 13 files changed, 320 insertions(+), 33 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/array_temporaries_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_d_lines_3.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_exp_4.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_exp_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_io_7.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_24.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_25.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_26.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_27.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_type_print_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/init_flag_20.f90

diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 73f5389361d..af89a5d2faf 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -32,6 +32,20 @@ along with GCC; see the file COPYING3.  If not see
 
 gfc_option_t gfc_option;
 
+#define SET_FLAG(flag, condition, on_value, off_value) \
+  do \
+    { \
+      if (condition) \
+	flag = (on_value); \
+      else \
+	flag = (off_value); \
+    } while (0)
+
+#define SET_BITFLAG2(m) m
+
+#define SET_BITFLAG(flag, condition, value) \
+  SET_BITFLAG2 (SET_FLAG (flag, condition, (flag | (value)), (flag & ~(value))))
+
 
 /* Set flags that control warnings and errors for different
    Fortran standards to their default values.  Keep in sync with
@@ -47,29 +61,46 @@ set_default_std_flags (void)
   gfc_option.warn_std = GFC_STD_F2018_DEL | GFC_STD_F95_DEL | GFC_STD_LEGACY;
 }
 
-
-/* Set all the DEC extension flags.  */
+/* Set (or unset) the DEC extension flags.  */
 
 static void
 set_dec_flags (int value)
 {
+  /* Allow legacy code without warnings.
+     Nb. We do not unset the allowed standards with value == 0 because
+     they are set by default in set_default_std_flags.  */
   if (value)
-    {
-      /* Allow legacy code without warnings.  */
-      gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
-        | GFC_STD_GNU | GFC_STD_LEGACY;
-      gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
-    }
-
-  /* Set other DEC compatibility extensions.  */
-  flag_dollar_ok |= value;
-  flag_cray_pointer |= value;
-  flag_dec_structure |= value;
-  flag_dec_intrinsic_ints |= value;
-  flag_dec_static |= value;
-  flag_dec_math |= value;
+    gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
+      | GFC_STD_GNU | GFC_STD_LEGACY;
+
+  SET_BITFLAG (gfc_option.warn_std, !value, GFC_STD_LEGACY);
+  SET_BITFLAG (gfc_option.warn_std, !value, GFC_STD_F95_DEL);
+
+  /* Set (or unset) other DEC compatibility extensions.  */
+  SET_BITFLAG (flag_dollar_ok, value, value);
+  SET_BITFLAG (flag_cray_pointer, value, value);
+  SET_BITFLAG (flag_dec_structure, value, value);
+  SET_BITFLAG (flag_dec_intrinsic_ints, value, value);
+  SET_BITFLAG (flag_dec_static, value, value);
+  SET_BITFLAG (flag_dec_math, value, value);
 }
 
+/* Enable (or disable) -finit-local-zero.  */
+
+static void
+set_init_local_zero (int value)
+{
+  gfc_option.flag_init_integer_value = 0;
+  gfc_option.flag_init_character_value = (char)0;
+
+  SET_FLAG (gfc_option.flag_init_integer, value, GFC_INIT_INTEGER_ON,
+	    GFC_INIT_INTEGER_OFF);
+  SET_FLAG (gfc_option.flag_init_logical, value, GFC_INIT_LOGICAL_FALSE,
+	    GFC_INIT_LOGICAL_OFF);
+  SET_FLAG (gfc_option.flag_init_character, value, GFC_INIT_CHARACTER_ON,
+	    GFC_INIT_CHARACTER_OFF);
+  SET_FLAG (flag_init_real, value, GFC_INIT_REAL_ZERO, GFC_INIT_REAL_OFF);
+}
 
 /* Return language mask for Fortran options.  */
 
@@ -107,11 +138,7 @@ gfc_init_options (unsigned int decoded_options_count,
 
   gfc_option.flag_preprocessed = 0;
   gfc_option.flag_d_lines = -1;
-  gfc_option.flag_init_integer = GFC_INIT_INTEGER_OFF;
-  gfc_option.flag_init_integer_value = 0;
-  gfc_option.flag_init_logical = GFC_INIT_LOGICAL_OFF;
-  gfc_option.flag_init_character = GFC_INIT_CHARACTER_OFF;
-  gfc_option.flag_init_character_value = (char)0;
+  set_init_local_zero (0);
   
   gfc_option.fpe = 0;
   /* All except GFC_FPE_INEXACT.  */
@@ -604,7 +631,7 @@ gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
       break;
 
     case OPT_fcheck_array_temporaries:
-      gfc_option.rtcheck |= GFC_RTCHECK_ARRAY_TEMPS;
+      SET_BITFLAG (gfc_option.rtcheck, value, GFC_RTCHECK_ARRAY_TEMPS);
       break;
       
     case OPT_fd_lines_as_code:
@@ -654,12 +681,7 @@ gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
       break;
 
     case OPT_finit_local_zero:
-      gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON;
-      gfc_option.flag_init_integer_value = 0;
-      flag_init_real = GFC_INIT_REAL_ZERO;
-      gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE;
-      gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON;
-      gfc_option.flag_init_character_value = (char)0;
+      set_init_local_zero (value);
       break;
 
     case OPT_finit_logical_:
@@ -759,11 +781,7 @@ gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
 
     case OPT_fdec:
       /* Enable all DEC extensions.  */
-      set_dec_flags (1);
-      break;
-
-    case OPT_fdec_structure:
-      flag_dec_structure = 1;
+      set_dec_flags (value);
       break;
     }
 
@@ -855,3 +873,7 @@ gfc_get_option_string (void)
   result[--pos] = '\0';
   return result;
 }
+
+#undef SET_BITFLAG
+#undef SET_BITFLAG2
+#undef SET_FLAG
diff --git a/gcc/testsuite/gfortran.dg/array_temporaries_5.f90 b/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
new file mode 100644
index 00000000000..dd147ba38ed
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
@@ -0,0 +1,10 @@
+! { dg-do run }
+! { dg-options "-fcheck-array-temporaries -fno-check-array-temporaries" }
+!
+! PR fortran/87919
+!
+! Ensure -fno-check-array-temporaries disables array temporary checking.
+!
+
+! Note that 'include' drops the dg-output check from the original test case.
+include 'array_temporaries_2.f90'
diff --git a/gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90 b/gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90
new file mode 100644
index 00000000000..88887c16f8e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-options "-std=legacy -fdec -fno-dec" }
+!
+! Make sure -fno-dec disables bitwise ops and check for the right errors.
+! -std=legacy is added to avoid the .XOR. extension warning.
+!
+
+implicit none
+
+integer i
+
+i = 3  .AND. 5 ! { dg-error "Operands of logical operator" }
+i = 3  .EQV. 5 ! { dg-error "Operands of logical operator" }
+i = 3 .NEQV. 5 ! { dg-error "Operands of logical operator" }
+i =    .NOT. 5 ! { dg-error "Operand of" }
+i = 3   .OR. 5 ! { dg-error "Operands of logical operator" }
+i = 3  .XOR. 5 ! { dg-error "Operands of logical operator" }
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_d_lines_3.f b/gcc/testsuite/gfortran.dg/dec_d_lines_3.f
new file mode 100644
index 00000000000..fb35923712b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_d_lines_3.f
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form -fno-dec" }
+!
+! Ensure -fd-lines-as-comments is not enabled by default without -fdec.
+!
+
+d     ! { dg-error "Non-numeric character in statement label" }
+D     ! { dg-error "Non-numeric character in statement label" }
+
+      end
diff --git a/gcc/testsuite/gfortran.dg/dec_exp_4.f90 b/gcc/testsuite/gfortran.dg/dec_exp_4.f90
new file mode 100644
index 00000000000..a9c6998d712
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_exp_4.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec" }
+!
+! Same as dec_exp_2, but make sure -fno-dec disables -fdec.
+!
+
+implicit none
+
+real, parameter :: r1 = 8e ! { dg-error "Missing exponent" }
+real, volatile :: r2
+r2 = 8e ! { dg-error "Missing exponent" }
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_exp_5.f90 b/gcc/testsuite/gfortran.dg/dec_exp_5.f90
new file mode 100644
index 00000000000..ce14860418f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_exp_5.f90
@@ -0,0 +1,15 @@
+! { dg-do run "xfail *-*-*" }
+! { dg-options "-fdec -fno-dec" }
+!
+! Same as dec_exp_3, but make sure -fno-dec disables -fdec.
+!
+
+implicit none
+
+real :: r
+character(2) :: s
+s = '8e'
+
+read (s, *) r ! { XFAIL "Bad real number" }
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_io_7.f90 b/gcc/testsuite/gfortran.dg/dec_io_7.f90
new file mode 100644
index 00000000000..339b8896169
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_io_7.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec" }
+!
+! Make sure -fno-dec rejects -fdec I/O specifiers.
+!
+
+implicit none
+
+integer, parameter :: fd=3
+character(*), parameter :: fname="test.txt"
+
+open (unit=fd, file=fname, readonly) ! { dg-error "is a DEC extension" }
+open (unit=fd, file=fname, action='read', shared) ! { dg-error "is a DEC extension" }
+open (unit=fd, file=fname, action='read', share='DENYNONE') ! { dg-error "is a DEC extension" }
+open (unit=fd, file=fname, action='write', noshared) ! { dg-error "is a DEC extension" }
+open (unit=fd, file=fname, action='write', share='DENYRW') ! { dg-error "is a DEC extension" }
+open(unit=fd,  file=fname, action ='WRITE', carriagecontrol='FORTRAN') ! { dg-error "is a DEC extension" }
+open(unit=fd,  file=fname, action ='WRITE', carriagecontrol='LIST') ! { dg-error "is a DEC extension" }
+open(unit=fd,  file=fname, action ='WRITE', carriagecontrol='NONE') ! { dg-error "is a DEC extension" }
+
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_24.f b/gcc/testsuite/gfortran.dg/dec_structure_24.f
new file mode 100644
index 00000000000..410d3af4080
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_24.f
@@ -0,0 +1,21 @@
+! { dg-do compile }
+!
+! PR fortran/87919
+!
+! Should fail to compile without the -fdec or -fdec-structure options.
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+
+      program test
+
+        structure /info/ ! { dg-error "-fdec-structure" }
+          integer a
+          real b
+         end structure   ! { dg-error "END PROGRAM" }
+
+        record /info/ s  ! { dg-error "-fdec-structure" }
+        s.a = 199        ! { dg-error "Unclassifiable" }
+        s.b = 7.6        ! { dg-error "Unclassifiable" }
+        write (*,*) s.a  ! { dg-error "Syntax error in WRITE" }
+        write (*,*) s.b  ! { dg-error "Syntax error in WRITE" }
+      end program test
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_25.f b/gcc/testsuite/gfortran.dg/dec_structure_25.f
new file mode 100644
index 00000000000..4f1ea58b8d0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_25.f
@@ -0,0 +1,22 @@
+! { dg-do run }
+! { dg-options "-fdec" }
+!
+! PR fortran/87919
+!
+! Should compile and run with the -fdec option.
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+      program test
+
+        structure /info/
+          integer a
+          real b
+         end structure
+
+        record /info/ s
+        s.a = 199
+        s.b = 7.6
+        if (s.a .ne. 199) stop 1
+        if (abs(s.b - 7.6) .gt. 1e-5) stop 2
+      end program test
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_26.f b/gcc/testsuite/gfortran.dg/dec_structure_26.f
new file mode 100644
index 00000000000..186d72f622c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_26.f
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec-structure" }
+!
+! PR fortran/87919
+!
+! Should fail to compile with -fdec and -fno-dec-structure.
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+      program test
+
+        structure /info/ ! { dg-error "-fdec-structure" }
+          integer a
+          real b
+         end structure   ! { dg-error "END PROGRAM" }
+
+        record /info/ s  ! { dg-error "-fdec-structure" }
+        s.a = 199        ! { dg-error "Unclassifiable" }
+        s.b = 7.6        ! { dg-error "Unclassifiable" }
+        write (*,*) s.a  ! { dg-error "Syntax error in WRITE" }
+        write (*,*) s.b  ! { dg-error "Syntax error in WRITE" }
+      end program test
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_27.f b/gcc/testsuite/gfortran.dg/dec_structure_27.f
new file mode 100644
index 00000000000..233aa38ab36
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_27.f
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure -fno-dec-structure" }
+!
+! PR fortran/87919
+!
+! Should fail to compile with -fdec-structure and -fno-dec-structure.
+!
+      program test
+
+        structure /info/ ! { dg-error "-fdec-structure" }
+          integer a
+          real b
+         end structure   ! { dg-error "END PROGRAM" }
+
+        record /info/ s  ! { dg-error "-fdec-structure" }
+        s.a = 199        ! { dg-error "Unclassifiable" }
+        s.b = 7.6        ! { dg-error "Unclassifiable" }
+        write (*,*) s.a  ! { dg-error "Syntax error in WRITE" }
+        write (*,*) s.b  ! { dg-error "Syntax error in WRITE" }
+      end program test
diff --git a/gcc/testsuite/gfortran.dg/dec_type_print_3.f90 b/gcc/testsuite/gfortran.dg/dec_type_print_3.f90
new file mode 100644
index 00000000000..5a9334c8c98
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_type_print_3.f90
@@ -0,0 +1,29 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec" }
+!
+! Ensure that -fno-dec disables the usage of TYPE as an alias for PRINT.
+!
+
+implicit none
+
+integer i /0/, j /1/, k /2/
+character(*), parameter :: fmtstr = "(A11)"
+namelist /nmlist/ i, j, k
+integer, parameter :: n = 5
+
+! Type as alias for print
+type* ! { dg-error "Invalid character in name" }
+type * ! { dg-error "Invalid character in name" }
+type*,'St','ar' ! { dg-error "Invalid character in name" }
+type *, 'St', 'ar' ! { dg-error "Invalid character in name" }
+type 10, 'Integer literal' ! { dg-error "Invalid character in name" }
+type 10, 'Integer variable' ! { dg-error "Invalid character in name" }
+type '(A11)', 'Character literal' ! { dg-error "Invalid character in name" }
+type fmtstr, 'Character variable' ! { dg-error "Unclassifiable statement" }
+type nmlist ! { dg-error "NAMELIST attribute.*?conflicts with PROCEDURE" }
+
+if (n .eq. n) type*, fmtstr ! { dg-error "Cannot assign to a named constant" }
+
+10    format (A11)
+
+end program
diff --git a/gcc/testsuite/gfortran.dg/init_flag_20.f90 b/gcc/testsuite/gfortran.dg/init_flag_20.f90
new file mode 100644
index 00000000000..e05cf951f4c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/init_flag_20.f90
@@ -0,0 +1,62 @@
+! { dg-do compile }
+! { dg-options "-finit-local-zero -fno-init-local-zero -fdump-tree-original" }
+!
+! PR fortran/87919
+!
+! Make sure -fno-init-local-zero disables -finit-local-zero.
+!
+! The basic test subroutines are copied from init_flag_1.f90, but this test
+! only compiles and check the original tree. The conditional checks are only
+! kept to prevent the variables from being marked unused.
+!
+
+subroutine real_test
+  real r1
+  real r2(10)
+  dimension r3(10,10)
+  if (r1 /= 0.0) STOP 1
+  if (r2(2) /= 0.0) STOP 2
+  if (r3(5,5) /= 0.0) STOP 3
+  if (r4 /= 0.0) STOP 4
+end subroutine real_test
+
+subroutine logical_test
+  logical l1
+  logical l2(2)
+  if (l1 .neqv. .false.) STOP 5
+  if (l2(2) .neqv. .false.) STOP 6
+end subroutine logical_test
+
+subroutine int_test
+  integer i1
+  integer i2(10)
+  dimension i3(10,10)
+  if (i1 /= 0) STOP 7
+  if (i2(2) /= 0) STOP 8
+  if (i3(5,5) /= 0) STOP 9
+  if (i4 /= 0) STOP 10
+end subroutine int_test
+
+subroutine complex_test
+  complex c1
+  complex c2(20,20)
+  if (c1 /= (0.0,0.0)) STOP 11
+  if (c2(1,1) /= (0.0,0.0)) STOP 12
+end subroutine complex_test
+
+subroutine char_test
+  character*1 c1
+  character*8 c2, c3(5)
+  character c4(10)
+  if (c1 /= '\0') STOP 13
+  if (c2 /= '\0\0\0\0\0\0\0\0') STOP 14
+  if (c3(1) /= '\0\0\0\0\0\0\0\0') STOP 15
+  if (c3(5) /= '\0\0\0\0\0\0\0\0') STOP 16
+  if (c4(5) /= '\0') STOP 17
+end subroutine char_test
+
+! Make sure no initialization code is generated.
+! { dg-final { scan-tree-dump-times "r\[1-4] *= *\[0\{]" 0 "original" } }
+! { dg-final { scan-tree-dump-times "l\[12] *= *\[0\{]" 0 "original" } }
+! { dg-final { scan-tree-dump-times "i\[1-4] *= *\[0\{]" 0 "original" } }
+! { dg-final { scan-tree-dump-times "memmove *\[(]\[^,]*c\[1-4]" 0 "original" } }
Jakub Jelinek Nov. 8, 2018, 5:53 p.m. | #5
On Thu, Nov 08, 2018 at 12:09:33PM -0500, Fritz Reese wrote:
> I find "expand" a more helpful name than "set_bitflag_1" since it
> describes what the macro does. However, I don't think it makes too
> much of a difference so I'll follow your preference (but I'll use
> SET_BITFLAG2 since then the definition line fits in 80 characters).

Ok.

> > What about the
> >       /* Allow legacy code without warnings.  */
> >       gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
> >         | GFC_STD_GNU | GFC_STD_LEGACY;
> >       gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
> > that is done for value, shouldn't set_dec_flags remove those
> > flags again?  Maybe not the allow_std ones, because those are set already by
> > default, perhaps just the warn_std flags?
> >
> 
> Sure. I wasn't convinced about this and how it might interplay with
> -std= so I left it alone, but I suppose it makes sense to unsuppress
> the warnings when disabling -fdec.

Perhaps it might be better not to change the allow_std/warn_std flags
during the option parsing, instead set or clear say flag_dec and
only when option processing is being finalized (gfc_post_options)
check if flag_dec is set and set those.  It would change behavior of
-fdec -std=f2018 and similar though.  Not sure what users expect.

> Strictly speaking it's not an exact copy because it omits the final {
> dg-output } check for the runtime warning, since the warning is
> supposed to occur in array_temporaries_2.f90 but not in the new case
> array_temporaries_5.f90. I assumed include would propagate the {
> dg-output } check -- upon actually testing this, it appears that is
> not the case. I find this misleading at a glance, but it works, so I
> don't mind this with an extra comment line.

Directives are only processed in the current file, so it doesn't really
matter what the included file has as directives.  One could even have the
included one be with expected dg-error lines and then include it in
the ones that don't expect any.

Anyway, that is all from me, I still don't want to stomp on Fortran
maintainer's review (use my global reviewer's rights for that) and
thus I'm deferring the review to them.  When committing, please make sure
to include Mark's email in the ChangeLog next to yours to credit him.

	Jakub
Fritz Reese Nov. 12, 2018, 8:28 p.m. | #6
On Thu, Nov 8, 2018 at 12:54 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Thu, Nov 08, 2018 at 12:09:33PM -0500, Fritz Reese wrote:
> > > What about the
> > >       /* Allow legacy code without warnings.  */
> > >       gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
> > >         | GFC_STD_GNU | GFC_STD_LEGACY;
> > >       gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
> > > that is done for value, shouldn't set_dec_flags remove those
> > > flags again?  Maybe not the allow_std ones, because those are set already by
> > > default, perhaps just the warn_std flags?
> > >
> >
> > Sure. I wasn't convinced about this and how it might interplay with
> > -std= so I left it alone, but I suppose it makes sense to unsuppress
> > the warnings when disabling -fdec.
>
> Perhaps it might be better not to change the allow_std/warn_std flags
> during the option parsing, instead set or clear say flag_dec and
> only when option processing is being finalized (gfc_post_options)
> check if flag_dec is set and set those.  It would change behavior of
> -fdec -std=f2018 and similar though.  Not sure what users expect.
>

Actually, the gcc frontend appears to move -std= before the
language-specific options before f951 is even executed regardless of
its location compared to the -fdec flags. I don't know if this is a
bug or if it is by design -- the feeling I get is that the gcc
frontend processes it first since it is recognized before the flang
specific options. Therefore, greedily setting the standard options the
first time flag_dec appears means the standard information is lost and
I believe your suggestion is correct: the standard flags must be set
only once in gfc_post_options.

In fact the new testcase dec_bitwise_ops_3.f90 is a good test of this:
it uses -fdec -fno-dec -std=legacy to avoid warnings for XOR. With the
version posted previously, the -std=legacy is overwritten by -fno-dec
and warnings still appear. Here's what I'd change from the previous
patch to support this:

diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index af89a5d2faf..b7f7360215c 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -66,16 +66,6 @@ set_default_std_flags (void)
 static void
 set_dec_flags (int value)
 {
-  /* Allow legacy code without warnings.
-     Nb. We do not unset the allowed standards with value == 0 because
-     they are set by default in set_default_std_flags.  */
-  if (value)
-    gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
-      | GFC_STD_GNU | GFC_STD_LEGACY;
-
-  SET_BITFLAG (gfc_option.warn_std, !value, GFC_STD_LEGACY);
-  SET_BITFLAG (gfc_option.warn_std, !value, GFC_STD_F95_DEL);
-
   /* Set (or unset) other DEC compatibility extensions.  */
   SET_BITFLAG (flag_dollar_ok, value, value);
   SET_BITFLAG (flag_cray_pointer, value, value);
@@ -85,6 +75,24 @@ set_dec_flags (int value)
   SET_BITFLAG (flag_dec_math, value, value);
 }

+/* Finalize DEC flags.  */
+
+static void
+post_dec_flags (int value)
+{
+  /* Don't warn for legacy code if -fdec is given; however, setting -fno-dec
+     does not force these warnings.  We make one final determination on this
+     at the end because -std= is always set first; thus, we can avoid
+     clobbering the user's desired standard settings in gfc_handle_option
+     e.g. when -fdec and -fno-dec are both given.  */
+  if (value)
+    {
+      gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
+       | GFC_STD_GNU | GFC_STD_LEGACY;
+      gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
+    }
+}
+
 /* Enable (or disable) -finit-local-zero.  */

 static void
@@ -248,6 +256,9 @@ gfc_post_options (const char **pfilename)
   char *source_path;
   int i;

+  /* Finalize DEC flags.  */
+  post_dec_flags (flag_dec);
+
   /* Excess precision other than "fast" requires front-end
      support.  */
   if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD)
@@

> Directives are only processed in the current file, so it doesn't really
> matter what the included file has as directives.  One could even have the
> included one be with expected dg-error lines and then include it in
> the ones that don't expect any.

Good to know, thanks! In that case, I like your suggestion of reducing
the test cases to includes. See new the newly attached patch for
updated cases.

> Anyway, that is all from me, I still don't want to stomp on Fortran
> maintainer's review (use my global reviewer's rights for that) and
> thus I'm deferring the review to them.  When committing, please make sure
> to include Mark's email in the ChangeLog next to yours to credit him.

Thanks for your comments. I think nobody will feel stomped on since
maintainers are sparse and busy. I will certainly make note of Mark's
contributions when committing.

Attached is the latest version, which builds and regtests cleanly on
x86_64-redhat-linux. OK for trunk, 7-branch, and 8-branch?

Fritz

From 1cae11a88b29fe521e0e6c6c7c1796a7adb34cad Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Mon, 12 Nov 2018 13:57:25 -0500
Subject: [PATCH] PR fortran/87919

Fix handling -fno-* prefix for init-local-zero, check-array-temporaries and dec.

gcc/fortran/
    * options.c (SET_FLAG, SET_BITFLAG, SET_BITFLAG2): New macros.
    (set_dec_flags): Set/unset DEC and std flags according to value.
    (set_init_local_zero): New helper for -finit-local-zero flag group.
    (gfc_init_options): Fix disabling of init flags, array temporaries
    check, and dec flags when value is zero (from -fno-*).

gcc/testsuiste/
    * gfortran.dg/array_temporaries_5.f90: New test.
    * gfortran.dg/dec_bitwise_ops_3.f90: Ditto.
    * gfortran.dg/dec_d_lines_3.f: Ditto.
    * gfortran.dg/dec_exp_4.f90: Ditto.
    * gfortran.dg/dec_exp_5.f90: Ditto.
    * gfortran.dg/dec_io_7.f90: Ditto.
    * gfortran.dg/dec_structure_24.f90: Ditto.
    * gfortran.dg/dec_structure_25.f90: Ditto.
    * gfortran.dg/dec_structure_26.f90: Ditto.
    * gfortran.dg/dec_structure_27.f90: Ditto.
    * gfortran.dg/dec_type_print_3.f90: Ditto.
    * gfortran.dg/init_flag_20.f90: Ditto.
---
 gcc/fortran/options.c                             | 93 +++++++++++++++--------
 gcc/testsuite/gfortran.dg/array_temporaries_5.f90 | 10 +++
 gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90   | 29 +++++++
 gcc/testsuite/gfortran.dg/dec_d_lines_3.f         | 14 ++++
 gcc/testsuite/gfortran.dg/dec_exp_4.f90           | 12 +++
 gcc/testsuite/gfortran.dg/dec_exp_5.f90           | 11 +++
 gcc/testsuite/gfortran.dg/dec_io_7.f90            | 20 +++++
 gcc/testsuite/gfortran.dg/dec_structure_24.f90    | 32 ++++++++
 gcc/testsuite/gfortran.dg/dec_structure_25.f90    | 11 +++
 gcc/testsuite/gfortran.dg/dec_structure_26.f90    | 34 +++++++++
 gcc/testsuite/gfortran.dg/dec_structure_27.f90    | 34 +++++++++
 gcc/testsuite/gfortran.dg/dec_type_print_3.f90    | 21 +++++
 gcc/testsuite/gfortran.dg/init_flag_20.f90        | 15 ++++
 13 files changed, 306 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/array_temporaries_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_d_lines_3.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_exp_4.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_exp_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_io_7.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_24.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_25.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_26.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_27.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_type_print_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/init_flag_20.f90
From 1cae11a88b29fe521e0e6c6c7c1796a7adb34cad Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Mon, 12 Nov 2018 13:57:25 -0500
Subject: [PATCH] PR fortran/87919

Fix handling -fno-* prefix for init-local-zero, check-array-temporaries and dec.

gcc/fortran/
	* options.c (SET_FLAG, SET_BITFLAG, SET_BITFLAG2): New macros.
	(set_dec_flags): Set/unset DEC and std flags according to value.
	(set_init_local_zero): New helper for -finit-local-zero flag group.
	(gfc_init_options): Fix disabling of init flags, array temporaries
	check, and dec flags when value is zero (from -fno-*).

gcc/testsuiste/
	* gfortran.dg/array_temporaries_5.f90: New test.
	* gfortran.dg/dec_bitwise_ops_3.f90: Ditto.
	* gfortran.dg/dec_d_lines_3.f: Ditto.
	* gfortran.dg/dec_exp_4.f90: Ditto.
	* gfortran.dg/dec_exp_5.f90: Ditto.
	* gfortran.dg/dec_io_7.f90: Ditto.
	* gfortran.dg/dec_structure_24.f90: Ditto.
	* gfortran.dg/dec_structure_25.f90: Ditto.
	* gfortran.dg/dec_structure_26.f90: Ditto.
	* gfortran.dg/dec_structure_27.f90: Ditto.
	* gfortran.dg/dec_type_print_3.f90: Ditto.
	* gfortran.dg/init_flag_20.f90: Ditto.
---
 gcc/fortran/options.c                             | 93 +++++++++++++++--------
 gcc/testsuite/gfortran.dg/array_temporaries_5.f90 | 10 +++
 gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90   | 29 +++++++
 gcc/testsuite/gfortran.dg/dec_d_lines_3.f         | 14 ++++
 gcc/testsuite/gfortran.dg/dec_exp_4.f90           | 12 +++
 gcc/testsuite/gfortran.dg/dec_exp_5.f90           | 11 +++
 gcc/testsuite/gfortran.dg/dec_io_7.f90            | 20 +++++
 gcc/testsuite/gfortran.dg/dec_structure_24.f90    | 32 ++++++++
 gcc/testsuite/gfortran.dg/dec_structure_25.f90    | 11 +++
 gcc/testsuite/gfortran.dg/dec_structure_26.f90    | 34 +++++++++
 gcc/testsuite/gfortran.dg/dec_structure_27.f90    | 34 +++++++++
 gcc/testsuite/gfortran.dg/dec_type_print_3.f90    | 21 +++++
 gcc/testsuite/gfortran.dg/init_flag_20.f90        | 15 ++++
 13 files changed, 306 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/array_temporaries_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_d_lines_3.f
 create mode 100644 gcc/testsuite/gfortran.dg/dec_exp_4.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_exp_5.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_io_7.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_24.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_25.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_26.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_27.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_type_print_3.f90
 create mode 100644 gcc/testsuite/gfortran.dg/init_flag_20.f90

diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 73f5389361d..b7f7360215c 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -32,6 +32,20 @@ along with GCC; see the file COPYING3.  If not see
 
 gfc_option_t gfc_option;
 
+#define SET_FLAG(flag, condition, on_value, off_value) \
+  do \
+    { \
+      if (condition) \
+	flag = (on_value); \
+      else \
+	flag = (off_value); \
+    } while (0)
+
+#define SET_BITFLAG2(m) m
+
+#define SET_BITFLAG(flag, condition, value) \
+  SET_BITFLAG2 (SET_FLAG (flag, condition, (flag | (value)), (flag & ~(value))))
+
 
 /* Set flags that control warnings and errors for different
    Fortran standards to their default values.  Keep in sync with
@@ -47,29 +61,54 @@ set_default_std_flags (void)
   gfc_option.warn_std = GFC_STD_F2018_DEL | GFC_STD_F95_DEL | GFC_STD_LEGACY;
 }
 
-
-/* Set all the DEC extension flags.  */
+/* Set (or unset) the DEC extension flags.  */
 
 static void
 set_dec_flags (int value)
 {
+  /* Set (or unset) other DEC compatibility extensions.  */
+  SET_BITFLAG (flag_dollar_ok, value, value);
+  SET_BITFLAG (flag_cray_pointer, value, value);
+  SET_BITFLAG (flag_dec_structure, value, value);
+  SET_BITFLAG (flag_dec_intrinsic_ints, value, value);
+  SET_BITFLAG (flag_dec_static, value, value);
+  SET_BITFLAG (flag_dec_math, value, value);
+}
+
+/* Finalize DEC flags.  */
+
+static void
+post_dec_flags (int value)
+{
+  /* Don't warn for legacy code if -fdec is given; however, setting -fno-dec
+     does not force these warnings.  We make one final determination on this
+     at the end because -std= is always set first; thus, we can avoid
+     clobbering the user's desired standard settings in gfc_handle_option
+     e.g. when -fdec and -fno-dec are both given.  */
   if (value)
     {
-      /* Allow legacy code without warnings.  */
       gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
-        | GFC_STD_GNU | GFC_STD_LEGACY;
+	| GFC_STD_GNU | GFC_STD_LEGACY;
       gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
     }
-
-  /* Set other DEC compatibility extensions.  */
-  flag_dollar_ok |= value;
-  flag_cray_pointer |= value;
-  flag_dec_structure |= value;
-  flag_dec_intrinsic_ints |= value;
-  flag_dec_static |= value;
-  flag_dec_math |= value;
 }
 
+/* Enable (or disable) -finit-local-zero.  */
+
+static void
+set_init_local_zero (int value)
+{
+  gfc_option.flag_init_integer_value = 0;
+  gfc_option.flag_init_character_value = (char)0;
+
+  SET_FLAG (gfc_option.flag_init_integer, value, GFC_INIT_INTEGER_ON,
+	    GFC_INIT_INTEGER_OFF);
+  SET_FLAG (gfc_option.flag_init_logical, value, GFC_INIT_LOGICAL_FALSE,
+	    GFC_INIT_LOGICAL_OFF);
+  SET_FLAG (gfc_option.flag_init_character, value, GFC_INIT_CHARACTER_ON,
+	    GFC_INIT_CHARACTER_OFF);
+  SET_FLAG (flag_init_real, value, GFC_INIT_REAL_ZERO, GFC_INIT_REAL_OFF);
+}
 
 /* Return language mask for Fortran options.  */
 
@@ -107,11 +146,7 @@ gfc_init_options (unsigned int decoded_options_count,
 
   gfc_option.flag_preprocessed = 0;
   gfc_option.flag_d_lines = -1;
-  gfc_option.flag_init_integer = GFC_INIT_INTEGER_OFF;
-  gfc_option.flag_init_integer_value = 0;
-  gfc_option.flag_init_logical = GFC_INIT_LOGICAL_OFF;
-  gfc_option.flag_init_character = GFC_INIT_CHARACTER_OFF;
-  gfc_option.flag_init_character_value = (char)0;
+  set_init_local_zero (0);
   
   gfc_option.fpe = 0;
   /* All except GFC_FPE_INEXACT.  */
@@ -221,6 +256,9 @@ gfc_post_options (const char **pfilename)
   char *source_path;
   int i;
 
+  /* Finalize DEC flags.  */
+  post_dec_flags (flag_dec);
+
   /* Excess precision other than "fast" requires front-end
      support.  */
   if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD)
@@ -604,7 +642,7 @@ gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
       break;
 
     case OPT_fcheck_array_temporaries:
-      gfc_option.rtcheck |= GFC_RTCHECK_ARRAY_TEMPS;
+      SET_BITFLAG (gfc_option.rtcheck, value, GFC_RTCHECK_ARRAY_TEMPS);
       break;
       
     case OPT_fd_lines_as_code:
@@ -654,12 +692,7 @@ gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
       break;
 
     case OPT_finit_local_zero:
-      gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON;
-      gfc_option.flag_init_integer_value = 0;
-      flag_init_real = GFC_INIT_REAL_ZERO;
-      gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE;
-      gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON;
-      gfc_option.flag_init_character_value = (char)0;
+      set_init_local_zero (value);
       break;
 
     case OPT_finit_logical_:
@@ -758,12 +791,8 @@ gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
       break;
 
     case OPT_fdec:
-      /* Enable all DEC extensions.  */
-      set_dec_flags (1);
-      break;
-
-    case OPT_fdec_structure:
-      flag_dec_structure = 1;
+      /* Set (or unset) the DEC extension flags.  */
+      set_dec_flags (value);
       break;
     }
 
@@ -855,3 +884,7 @@ gfc_get_option_string (void)
   result[--pos] = '\0';
   return result;
 }
+
+#undef SET_BITFLAG
+#undef SET_BITFLAG2
+#undef SET_FLAG
diff --git a/gcc/testsuite/gfortran.dg/array_temporaries_5.f90 b/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
new file mode 100644
index 00000000000..dd147ba38ed
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_temporaries_5.f90
@@ -0,0 +1,10 @@
+! { dg-do run }
+! { dg-options "-fcheck-array-temporaries -fno-check-array-temporaries" }
+!
+! PR fortran/87919
+!
+! Ensure -fno-check-array-temporaries disables array temporary checking.
+!
+
+! Note that 'include' drops the dg-output check from the original test case.
+include 'array_temporaries_2.f90'
diff --git a/gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90 b/gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90
new file mode 100644
index 00000000000..c28cf81fc04
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_bitwise_ops_3.f90
@@ -0,0 +1,29 @@
+! { dg-do compile }
+! { dg-options "-std=legacy -fdec -fno-dec" }
+!
+! PR fortran/87919
+!
+! Make sure -fno-dec disables bitwise ops and check for the right errors.
+! -std=legacy is added to avoid the .XOR. extension warning.
+!
+
+include 'dec_bitwise_ops_1.f90'
+
+! { dg-error "Operands of logical operator" " " { target *-*-* } 33 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 34 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 35 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 46 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 47 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 48 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 59 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 60 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 61 }
+! { dg-error "Operand of .not. operator" " " { target *-*-* } 72 }
+! { dg-error "Operand of .not. operator" " " { target *-*-* } 73 }
+! { dg-error "Operand of .not. operator" " " { target *-*-* } 74 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 85 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 86 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 87 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 98 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 99 }
+! { dg-error "Operands of logical operator" " " { target *-*-* } 100 }
diff --git a/gcc/testsuite/gfortran.dg/dec_d_lines_3.f b/gcc/testsuite/gfortran.dg/dec_d_lines_3.f
new file mode 100644
index 00000000000..2df4341c0e4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_d_lines_3.f
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! { dg-options "-ffixed-form -fdec -fno-dec" }
+!
+! PR fortran/87919
+!
+! Ensure -fno-dec disables -fdec, leaving d-lines as code by default.
+!
+
+include 'dec_d_lines_2.f'
+
+! { dg-error "character in statement label" " " { target *-*-*} 6 }
+! { dg-error "Unclassifiable statement" " " { target *-*-*} 6 }
+! { dg-error "character in statement label" " " { target *-*-*} 7 }
+! { dg-error "Unclassifiable statement" " " { target *-*-*} 7 }
diff --git a/gcc/testsuite/gfortran.dg/dec_exp_4.f90 b/gcc/testsuite/gfortran.dg/dec_exp_4.f90
new file mode 100644
index 00000000000..9d8b10db6a7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_exp_4.f90
@@ -0,0 +1,12 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec" }
+!
+! PR fortran/87919
+!
+! Make sure -fno-dec disables -fdec as with dec_exp_2.
+!
+
+include 'dec_exp_2.f90'
+
+! { dg-error "Missing exponent" "" { target *-*-* } 9 }
+! { dg-error "Missing exponent" "" { target *-*-* } 11 }
diff --git a/gcc/testsuite/gfortran.dg/dec_exp_5.f90 b/gcc/testsuite/gfortran.dg/dec_exp_5.f90
new file mode 100644
index 00000000000..faf3a9b306b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_exp_5.f90
@@ -0,0 +1,11 @@
+! { dg-do run "xfail *-*-*" }
+! { dg-options "-fdec -fno-dec" }
+!
+! PR fortran/87919
+!
+! Make sure -fno-dec disables -fdec as with dec_exp_3.
+!
+
+include 'dec_exp_3.f90'
+
+! { XFAIL "Bad real number" "" { target *-*-* } 13 }
diff --git a/gcc/testsuite/gfortran.dg/dec_io_7.f90 b/gcc/testsuite/gfortran.dg/dec_io_7.f90
new file mode 100644
index 00000000000..4a931c15fe7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_io_7.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec" }
+!
+! PR fortran/87919
+!
+! Make sure -fno-dec rejects -fdec I/O specifiers as with dec_io_1.
+!
+
+include 'dec_io_1.f90'
+
+! { dg-error "is a DEC extension" "" { target *-*-* } 12 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 24 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 58 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 64 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 68 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 74 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 78 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 84 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 90 }
+! { dg-error "is a DEC extension" "" { target *-*-* } 96 }
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_24.f90 b/gcc/testsuite/gfortran.dg/dec_structure_24.f90
new file mode 100644
index 00000000000..02842b315dc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_24.f90
@@ -0,0 +1,32 @@
+! { dg-do compile }
+!
+! PR fortran/87919
+!
+! Should fail to compile without the -fdec or -fdec-structure options.
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+
+include 'dec_structure_1.f90'
+
+! { dg-error "-fdec-structure" " " { target *-*-* } 14 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 19 }
+! { dg-error "-fdec-structure" " " { target *-*-* } 21 }
+! { dg-error "-fdec-structure" " " { target *-*-* } 22 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 25 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 26 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 27 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 28 }
+! { dg-error "is not a variable" " " { target *-*-* } 30 }
+! { dg-error "Bad character" " " { target *-*-* } 32 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 34 }
+! { dg-error "Bad character" " " { target *-*-* } 36 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 38 }
+! { dg-error "Bad character" " " { target *-*-* } 40 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 42 }
+! { dg-error "Bad character" " " { target *-*-* } 44 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 46 }
+! { dg-error "Bad character" " " { target *-*-* } 48 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 50 }
+! { dg-error "Bad character" " " { target *-*-* } 52 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 54 }
+! { dg-error "function result" " " { target *-*-* } 29 }
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_25.f90 b/gcc/testsuite/gfortran.dg/dec_structure_25.f90
new file mode 100644
index 00000000000..a64d85a88a4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_25.f90
@@ -0,0 +1,11 @@
+! { dg-do run }
+! { dg-options "-fdec" }
+!
+! PR fortran/87919
+!
+! Should compile and run with the -fdec option.
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+
+include 'dec_structure_1.f90'
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_26.f90 b/gcc/testsuite/gfortran.dg/dec_structure_26.f90
new file mode 100644
index 00000000000..7829103b995
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_26.f90
@@ -0,0 +1,34 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec-structure" }
+!
+! PR fortran/87919
+!
+! Should fail to compile with -fdec and -fno-dec-structure.
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+
+include 'dec_structure_1.f90'
+
+! { dg-error "-fdec-structure" " " { target *-*-* } 14 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 19 }
+! { dg-error "-fdec-structure" " " { target *-*-* } 21 }
+! { dg-error "-fdec-structure" " " { target *-*-* } 22 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 25 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 26 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 27 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 28 }
+! { dg-error "is not a variable" " " { target *-*-* } 30 }
+! { dg-error "Bad character" " " { target *-*-* } 32 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 34 }
+! { dg-error "Bad character" " " { target *-*-* } 36 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 38 }
+! { dg-error "Bad character" " " { target *-*-* } 40 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 42 }
+! { dg-error "Bad character" " " { target *-*-* } 44 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 46 }
+! { dg-error "Bad character" " " { target *-*-* } 48 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 50 }
+! { dg-error "Bad character" " " { target *-*-* } 52 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 54 }
+! { dg-error "function result" " " { target *-*-* } 29 }
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_27.f90 b/gcc/testsuite/gfortran.dg/dec_structure_27.f90
new file mode 100644
index 00000000000..1257365deb8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_27.f90
@@ -0,0 +1,34 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure -fno-dec-structure" }
+!
+! PR fortran/87919
+!
+! Should fail to compile with -fdec-structure and -fno-dec-structure.
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+
+include 'dec_structure_1.f90'
+
+! { dg-error "-fdec-structure" " " { target *-*-* } 14 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 19 }
+! { dg-error "-fdec-structure" " " { target *-*-* } 21 }
+! { dg-error "-fdec-structure" " " { target *-*-* } 22 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 25 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 26 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 27 }
+! { dg-error "Unclassifiable statement" " " { target *-*-* } 28 }
+! { dg-error "is not a variable" " " { target *-*-* } 30 }
+! { dg-error "Bad character" " " { target *-*-* } 32 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 34 }
+! { dg-error "Bad character" " " { target *-*-* } 36 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 38 }
+! { dg-error "Bad character" " " { target *-*-* } 40 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 42 }
+! { dg-error "Bad character" " " { target *-*-* } 44 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 46 }
+! { dg-error "Bad character" " " { target *-*-* } 48 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 50 }
+! { dg-error "Bad character" " " { target *-*-* } 52 }
+! { dg-error "Expecting END PROGRAM" " " { target *-*-* } 54 }
+! { dg-error "function result" " " { target *-*-* } 29 }
diff --git a/gcc/testsuite/gfortran.dg/dec_type_print_3.f90 b/gcc/testsuite/gfortran.dg/dec_type_print_3.f90
new file mode 100644
index 00000000000..f766bdf0022
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_type_print_3.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec" }
+!
+! PR fortran/87919
+!
+! Ensure that -fno-dec disables the usage of TYPE as an alias for PRINT.
+!
+
+include 'dec_type_print.f90'
+
+! { dg-error "Invalid character in name" "" { target *-*-* } 52 }
+! { dg-error "Invalid character in name" "" { target *-*-* } 53 }
+! { dg-error "Invalid character in name" "" { target *-*-* } 54 }
+! { dg-error "Invalid character in name" "" { target *-*-* } 55 }
+! { dg-error "Invalid character in name" "" { target *-*-* } 56 }
+! { dg-error "Invalid character in name" "" { target *-*-* } 57 }
+! { dg-error "Invalid character in name" "" { target *-*-* } 58 }
+! { dg-error "Unclassifiable statement" "" { target *-*-* } 59 }
+! { dg-error "conflicts with PROCEDURE" "" { target *-*-* } 60 }
+! { dg-error "Cannot assign to a named constant" "" { target *-*-* } 80 }
+
diff --git a/gcc/testsuite/gfortran.dg/init_flag_20.f90 b/gcc/testsuite/gfortran.dg/init_flag_20.f90
new file mode 100644
index 00000000000..6f15c1ace0d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/init_flag_20.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-fbackslash -finit-local-zero -fno-init-local-zero -fdump-tree-original" }
+!
+! PR fortran/87919
+!
+! Make sure -fno-init-local-zero disables -finit-local-zero.
+!
+
+include 'init_flag_1.f90'
+
+! Make sure no initialization code is generated.
+! { dg-final { scan-tree-dump-times "r\[1-4] *= *\[0\{]" 0 "original" } }
+! { dg-final { scan-tree-dump-times "l\[12] *= *\[0\{]" 0 "original" } }
+! { dg-final { scan-tree-dump-times "i\[1-4] *= *\[0\{]" 0 "original" } }
+! { dg-final { scan-tree-dump-times "memmove *\[(]\[^,]*c\[1-4]" 0 "original" } }
Jakub Jelinek Nov. 12, 2018, 8:42 p.m. | #7
On Mon, Nov 12, 2018 at 03:28:47PM -0500, Fritz Reese wrote:
> Actually, the gcc frontend appears to move -std= before the
> language-specific options before f951 is even executed regardless of
> its location compared to the -fdec flags. I don't know if this is a

That is because:
#define F951_OPTIONS        "%(cc1_options) %{J*} \
                             %{!nostdinc:-fintrinsic-modules-path finclude%s}\
                             %{!fsyntax-only:%(invoke_as)}"
and
static const char *cc1_options =
"%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
 %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
 %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*}\
 %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)} \
 %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}} \
 %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
 %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\

where %{std*&ansi&trigraphs} comes before %{f*}.
I guess let's not change that behavior.

> bug or if it is by design -- the feeling I get is that the gcc
> frontend processes it first since it is recognized before the flang
> specific options. Therefore, greedily setting the standard options the
> first time flag_dec appears means the standard information is lost and
> I believe your suggestion is correct: the standard flags must be set
> only once in gfc_post_options.
> 
> In fact the new testcase dec_bitwise_ops_3.f90 is a good test of this:
> it uses -fdec -fno-dec -std=legacy to avoid warnings for XOR. With the
> version posted previously, the -std=legacy is overwritten by -fno-dec
> and warnings still appear. Here's what I'd change from the previous
> patch to support this:

LGTM.

> > Anyway, that is all from me, I still don't want to stomp on Fortran
> > maintainer's review (use my global reviewer's rights for that) and
> > thus I'm deferring the review to them.  When committing, please make sure
> > to include Mark's email in the ChangeLog next to yours to credit him.
> 
> Thanks for your comments. I think nobody will feel stomped on since
> maintainers are sparse and busy. I will certainly make note of Mark's
> contributions when committing.

Ok, so I'll ack it for trunk now, but please give the other Fortran
maintainers one day to disagree before committing.
For the release branches, I'd wait two weeks or so before backporting it.

Thanks.

	Jakub
Fritz Reese Nov. 12, 2018, 8:52 p.m. | #8
On Mon, Nov 12, 2018 at 3:42 PM Jakub Jelinek <jakub@redhat.com> wrote:
> Ok, so I'll ack it for trunk now, but please give the other Fortran
> maintainers one day to disagree before committing.
> For the release branches, I'd wait two weeks or so before backporting it.
>

Roger that. I'll happily give it some time. Thanks for looking it over.

Fritz

Patch

diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 73f5389361d9..3b7c2d40fe8a 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -761,10 +761,6 @@  gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
       /* Enable all DEC extensions.  */
       set_dec_flags (1);
       break;
-
-    case OPT_fdec_structure:
-      flag_dec_structure = 1;
-      break;
     }
 
   Fortran_handle_option_auto (&global_options, &global_options_set, 
diff --git a/gcc/testsuite/gfortran.dg/pr87919-dec-structure-1.f b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-1.f
new file mode 100644
index 000000000000..4dd34082b97a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-1.f
@@ -0,0 +1,21 @@ 
+! { dg-do compile }
+!
+! PR/fortran/87919
+!
+! Should fail to compile without the -fdec or -fdec-structure options
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+
+      program test
+
+        structure /info/ ! { dg-error "-fdec-structure" }
+          integer a
+          real b
+         end structure   ! { dg-error "END PROGRAM" }
+
+        record /info/ s  ! { dg-error "-fdec-structure" }
+        s.a = 199        ! { dg-error "Unclassifiable" }
+        s.b = 7.6        ! { dg-error "Unclassifiable" }
+        write (*,*) s.a  ! { dg-error "Syntax error in WRITE" }
+        write (*,*) s.b  ! { dg-error "Syntax error in WRITE" }
+      end program test
diff --git a/gcc/testsuite/gfortran.dg/pr87919-dec-structure-2.f b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-2.f
new file mode 100644
index 000000000000..e2ebfe344abb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-2.f
@@ -0,0 +1,22 @@ 
+! { dg-do run }
+! { dg-options "-fdec" }
+!
+! PR/fortran/87919
+!
+! Should compile anf run with the -fdec option
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+     program test
+
+        structure /info/
+          integer a
+          real b
+         end structure
+
+        record /info/ s
+        s.a = 199
+        s.b = 7.6
+        if (s.a .ne. 199) stop 1
+        if (abs(s.b - 7.6) .gt. 1e-5) stop 2
+      end program test
diff --git a/gcc/testsuite/gfortran.dg/pr87919-dec-structure-3.f b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-3.f
new file mode 100644
index 000000000000..e543b37a4371
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-3.f
@@ -0,0 +1,22 @@ 
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! PR/fortran/87919
+!
+! Should compile anf run with the -fdec option
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+      program test
+
+        structure /info/
+          integer a
+          real b
+         end structure
+
+        record /info/ s
+        s.a = 199
+        s.b = 7.6
+        if (s.a .ne. 199) stop 1
+        if (abs(s.b - 7.6) .gt. 1e-5) stop 2
+      end program test
diff --git a/gcc/testsuite/gfortran.dg/pr87919-dec-structure-4.f b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-4.f
new file mode 100644
index 000000000000..fa5f1d7a3436
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr87919-dec-structure-4.f
@@ -0,0 +1,22 @@ 
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec-structure" }
+!
+! PR/fortran/87919
+!
+! Should fail to compile with the -fdec and -fno-dec-structure option
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+      program test
+
+        structure /info/ ! { dg-error "-fdec-structure" }
+          integer a
+          real b
+         end structure   ! { dg-error "END PROGRAM" }
+
+        record /info/ s  ! { dg-error "-fdec-structure" }
+        s.a = 199        ! { dg-error "Unclassifiable" }
+        s.b = 7.6        ! { dg-error "Unclassifiable" }
+        write (*,*) s.a  ! { dg-error "Syntax error in WRITE" }
+        write (*,*) s.b  ! { dg-error "Syntax error in WRITE" }
+      end program test