public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/gcc] rhel-f41-base: Add RHEL Fortran patchset.
Date: Mon, 29 Jun 2026 12:29:07 GMT [thread overview]
Message-ID: <178273614778.1.8220343257517380169.rpms-gcc-c7b83880f7d3@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/gcc
Branch : rhel-f41-base
Commit : c7b83880f7d31a09d20787b0dced6df9d390924e
Author : Jakub Jelinek <jakub@redhat.com>
Date : 2021-01-31T12:15:51+01:00
Stats : +4467/-0 in 11 file(s)
URL : https://src.fedoraproject.org/rpms/gcc/c/c7b83880f7d31a09d20787b0dced6df9d390924e?branch=rhel-f41-base
Log:
Add RHEL Fortran patchset.
---
diff --git a/gcc.spec b/gcc.spec
index a49fbbe..99687e5 100644
--- a/gcc.spec
+++ b/gcc.spec
@@ -273,6 +273,17 @@ Patch10: gcc11-rh1574936.patch
Patch11: gcc11-d-shared-libphobos.patch
Patch12: gcc11-pr98338-workaround.patch
+Patch100: gcc11-fortran-fdec-duplicates.patch
+Patch101: gcc11-fortran-flogical-as-integer.patch
+Patch102: gcc11-fortran-fdec-ichar.patch
+Patch103: gcc11-fortran-fdec-non-integer-index.patch
+Patch104: gcc11-fortran-fdec-old-init.patch
+Patch105: gcc11-fortran-fdec-override-kind.patch
+Patch106: gcc11-fortran-fdec-non-logical-if.patch
+Patch107: gcc11-fortran-fdec-promotion.patch
+Patch108: gcc11-fortran-fdec-sequence.patch
+Patch109: gcc11-fortran-fdec-add-missing-indexes.patch
+
# On ARM EABI systems, we do want -gnueabi to be part of the
# target triple.
%ifnarch %{arm}
@@ -784,6 +795,19 @@ to NVidia PTX capable devices if available.
%patch11 -p0 -b .d-shared-libphobos~
%patch12 -p0 -b .pr98338-workaround~
+%if %{?rhel} >= 9
+%patch100 -p1 -b .fortran-fdec-duplicates~
+%patch101 -p1 -b .fortran-flogical-as-integer~
+%patch102 -p1 -b .fortran-fdec-ichar~
+%patch103 -p1 -b .fortran-fdec-non-integer-index~
+%patch104 -p1 -b .fortran-fdec-old-init~
+%patch105 -p1 -b .fortran-fdec-override-kind~
+%patch106 -p1 -b .fortran-fdec-non-logical-if~
+%patch107 -p1 -b .fortran-fdec-promotion~
+%patch108 -p1 -b .fortran-fdec-sequence~
+%patch109 -p1 -b .fortran-fdec-add-missing-indexes~
+%endif
+
rm -f libgomp/testsuite/*/*task-detach*
echo 'Red Hat %{version}-%{gcc_release}' > gcc/DEV-PHASE
diff --git a/gcc11-fortran-fdec-add-missing-indexes.patch b/gcc11-fortran-fdec-add-missing-indexes.patch
new file mode 100644
index 0000000..d707b94
--- /dev/null
+++ b/gcc11-fortran-fdec-add-missing-indexes.patch
@@ -0,0 +1,181 @@
+From 7001d522d0273658d9e1fb12ca104d56bfcae34d Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 15:06:08 +0000
+Subject: [PATCH 10/10] Fill in missing array dimensions using the lower bound
+
+Use -fdec-add-missing-indexes to enable feature. Also enabled by fdec.
+---
+ gcc/fortran/lang.opt | 8 ++++++++
+ gcc/fortran/options.c | 1 +
+ gcc/fortran/resolve.c | 24 ++++++++++++++++++++++++
+ gcc/testsuite/gfortran.dg/array_6.f90 | 23 +++++++++++++++++++++++
+ gcc/testsuite/gfortran.dg/array_7.f90 | 23 +++++++++++++++++++++++
+ gcc/testsuite/gfortran.dg/array_8.f90 | 23 +++++++++++++++++++++++
+ 6 files changed, 102 insertions(+)
+ create mode 100644 gcc/testsuite/gfortran.dg/array_6.f90
+ create mode 100644 gcc/testsuite/gfortran.dg/array_7.f90
+ create mode 100644 gcc/testsuite/gfortran.dg/array_8.f90
+
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index 019c798cf09..f27de88ea3f 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -281,6 +281,10 @@ Wmissing-include-dirs
+ Fortran
+ ; Documented in C/C++
+
++Wmissing-index
++Fortran Var(warn_missing_index) Warning LangEnabledBy(Fortran,Wall)
++Warn that the lower bound of a missing index will be used.
++
+ Wuse-without-only
+ Fortran Var(warn_use_without_only) Warning
+ Warn about USE statements that have no ONLY qualifier.
+@@ -460,6 +464,10 @@ fdec
+ Fortran Var(flag_dec)
+ Enable all DEC language extensions.
+
++fdec-add-missing-indexes
++Fortran Var(flag_dec_add_missing_indexes)
++Enable the addition of missing indexes using their lower bounds.
++
+ fdec-blank-format-item
+ Fortran Var(flag_dec_blank_format_item)
+ Enable the use of blank format items in format strings.
+diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
+index 050f56fdc25..c3b2822685d 100644
+--- a/gcc/fortran/options.c
++++ b/gcc/fortran/options.c
+@@ -84,6 +84,7 @@ set_dec_flags (int value)
+ SET_BITFLAG (flag_dec_non_logical_if, value, value);
+ SET_BITFLAG (flag_dec_promotion, value, value);
+ SET_BITFLAG (flag_dec_sequence, value, value);
++ SET_BITFLAG (flag_dec_add_missing_indexes, value, value);
+ }
+
+ /* Finalize DEC flags. */
+diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
+index fe7d0cc5944..0efeedab46e 100644
+--- a/gcc/fortran/resolve.c
++++ b/gcc/fortran/resolve.c
+@@ -4806,6 +4806,30 @@ compare_spec_to_ref (gfc_array_ref *ar)
+ if (ar->type == AR_FULL)
+ return true;
+
++ if (flag_dec_add_missing_indexes && as->rank > ar->dimen)
++ {
++ /* Add in the missing dimensions, assuming they are the lower bound
++ of that dimension if not specified. */
++ int j;
++ if (warn_missing_index)
++ {
++ gfc_warning (OPT_Wmissing_index, "Using the lower bound for "
++ "unspecified dimensions in array reference at %L",
++ &ar->where);
++ }
++ /* Other parts of the code iterate ar->start and ar->end from 0 to
++ ar->dimen, so it is safe to assume slots from ar->dimen upwards
++ are unused (i.e. there are no gaps; the specified indexes are
++ contiguous and start at zero. */
++ for(j = ar->dimen; j <= as->rank; j++)
++ {
++ ar->start[j] = gfc_copy_expr (as->lower[j]);
++ ar->end[j] = gfc_copy_expr (as->lower[j]);
++ ar->dimen_type[j] = DIMEN_ELEMENT;
++ }
++ ar->dimen = as->rank;
++ }
++
+ if (as->rank != ar->dimen)
+ {
+ gfc_error ("Rank mismatch in array reference at %L (%d/%d)",
+diff --git a/gcc/testsuite/gfortran.dg/array_6.f90 b/gcc/testsuite/gfortran.dg/array_6.f90
+new file mode 100644
+index 00000000000..5c26e18ab3e
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/array_6.f90
+@@ -0,0 +1,23 @@
++! { dg-do run }
++! { dg-options "-fdec -Wmissing-index" }!
++! Checks that under-specified arrays (referencing arrays with fewer
++! dimensions than the array spec) generates a warning.
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Updated by Mark Eggleston <mark.eggleston@codethink.co.uk>
++!
++
++program under_specified_array
++ integer chessboard(8,8)
++ integer chessboard3d(8,8,3:5)
++ chessboard(3,1) = 5
++ chessboard(3,2) = 55
++ chessboard3d(4,1,3) = 6
++ chessboard3d(4,1,4) = 66
++ chessboard3d(4,4,3) = 7
++ chessboard3d(4,4,4) = 77
++
++ if (chessboard(3).ne.5) stop 1 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
++ if (chessboard3d(4).ne.6) stop 2 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
++ if (chessboard3d(4,4).ne.7) stop 3 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
++end program
+diff --git a/gcc/testsuite/gfortran.dg/array_7.f90 b/gcc/testsuite/gfortran.dg/array_7.f90
+new file mode 100644
+index 00000000000..5588a5bd02d
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/array_7.f90
+@@ -0,0 +1,23 @@
++! { dg-do run }
++! { dg-options "-fdec-add-missing-indexes -Wmissing-index" }!
++! Checks that under-specified arrays (referencing arrays with fewer
++! dimensions than the array spec) generates a warning.
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Updated by Mark Eggleston <mark.eggleston@codethink.co.uk>
++!
++
++program under_specified_array
++ integer chessboard(8,8)
++ integer chessboard3d(8,8,3:5)
++ chessboard(3,1) = 5
++ chessboard(3,2) = 55
++ chessboard3d(4,1,3) = 6
++ chessboard3d(4,1,4) = 66
++ chessboard3d(4,4,3) = 7
++ chessboard3d(4,4,4) = 77
++
++ if (chessboard(3).ne.5) stop 1 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
++ if (chessboard3d(4).ne.6) stop 2 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
++ if (chessboard3d(4,4).ne.7) stop 3 ! { dg-warning "Using the lower bound for unspecified dimensions in array reference" }
++end program
+diff --git a/gcc/testsuite/gfortran.dg/array_8.f90 b/gcc/testsuite/gfortran.dg/array_8.f90
+new file mode 100644
+index 00000000000..f0d2ef5e37d
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/array_8.f90
+@@ -0,0 +1,23 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-add-missing-indexes" }!
++! Checks that under-specified arrays (referencing arrays with fewer
++! dimensions than the array spec) generates a warning.
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Updated by Mark Eggleston <mark.eggleston@codethink.co.uk>
++!
++
++program under_specified_array
++ integer chessboard(8,8)
++ integer chessboard3d(8,8,3:5)
++ chessboard(3,1) = 5
++ chessboard(3,2) = 55
++ chessboard3d(4,1,3) = 6
++ chessboard3d(4,1,4) = 66
++ chessboard3d(4,4,3) = 7
++ chessboard3d(4,4,4) = 77
++
++ if (chessboard(3).ne.5) stop 1 ! { dg-error "Rank mismatch" }
++ if (chessboard3d(4).ne.6) stop 2 ! { dg-error "Rank mismatch" }
++ if (chessboard3d(4,4).ne.7) stop 3 ! { dg-error "Rank mismatch" }
++end program
+--
+2.27.0
+
diff --git a/gcc11-fortran-fdec-duplicates.patch b/gcc11-fortran-fdec-duplicates.patch
new file mode 100644
index 0000000..b5d1104
--- /dev/null
+++ b/gcc11-fortran-fdec-duplicates.patch
@@ -0,0 +1,215 @@
+From 23b1fcb104c666429451ffaf936f8da5fcd3d43a Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 12:29:47 +0000
+Subject: [PATCH 01/10] Allow duplicate declarations.
+
+Enabled by -fdec-duplicates and -fdec.
+
+Some fixes by Jim MacArthur <jim.macarthur@codethink.co.uk>
+Addition of -fdec-duplicates by Mark Eggleston <mark.eggleston@codethink.com>
+---
+ gcc/fortran/lang.opt | 4 ++++
+ gcc/fortran/options.c | 1 +
+ gcc/fortran/symbol.c | 21 +++++++++++++++++--
+ .../gfortran.dg/duplicate_type_4.f90 | 13 ++++++++++++
+ .../gfortran.dg/duplicate_type_5.f90 | 13 ++++++++++++
+ .../gfortran.dg/duplicate_type_6.f90 | 13 ++++++++++++
+ .../gfortran.dg/duplicate_type_7.f90 | 13 ++++++++++++
+ .../gfortran.dg/duplicate_type_8.f90 | 12 +++++++++++
+ .../gfortran.dg/duplicate_type_9.f90 | 12 +++++++++++
+ 9 files changed, 100 insertions(+), 2 deletions(-)
+ create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_4.f90
+ create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_5.f90
+ create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_6.f90
+ create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_7.f90
+ create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_8.f90
+ create mode 100644 gcc/testsuite/gfortran.dg/duplicate_type_9.f90
+
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index 2b1977c523b..52bd522051e 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -469,6 +469,10 @@ Fortran Var(flag_dec_char_conversions)
+ Enable the use of character literals in assignments and data statements
+ for non-character variables.
+
++fdec-duplicates
++Fortran Var(flag_dec_duplicates)
++Allow varibles to be duplicated in the type specification matches.
++
+ fdec-include
+ Fortran Var(flag_dec_include)
+ Enable legacy parsing of INCLUDE as statement.
+diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
+index 3a0b98bf1ec..f19ba87f8a0 100644
+--- a/gcc/fortran/options.c
++++ b/gcc/fortran/options.c
+@@ -77,6 +77,7 @@ set_dec_flags (int value)
+ SET_BITFLAG (flag_dec_format_defaults, value, value);
+ SET_BITFLAG (flag_dec_blank_format_item, value, value);
+ SET_BITFLAG (flag_dec_char_conversions, value, value);
++ SET_BITFLAG (flag_dec_duplicates, value, value);
+ }
+
+ /* Finalize DEC flags. */
+diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
+index 3b988d1be22..9843175cc2a 100644
+--- a/gcc/fortran/symbol.c
++++ b/gcc/fortran/symbol.c
+@@ -1995,6 +1995,8 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
+ if (sym->attr.result && type == BT_UNKNOWN && sym->ns->proc_name)
+ type = sym->ns->proc_name->ts.type;
+
++ flavor = sym->attr.flavor;
++
+ if (type != BT_UNKNOWN && !(sym->attr.function && sym->attr.implicit_type)
+ && !(gfc_state_stack->previous && gfc_state_stack->previous->previous
+ && gfc_state_stack->previous->previous->state == COMP_SUBMODULE)
+@@ -2007,6 +2009,23 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
+ else if (sym->attr.function && sym->attr.result)
+ gfc_error ("Symbol %qs at %L already has basic type of %s",
+ sym->ns->proc_name->name, where, gfc_basic_typename (type));
++ else if (flag_dec_duplicates)
++ {
++ /* Ignore temporaries and class/procedure names */
++ if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS
++ || sym->ts.type == BT_PROCEDURE)
++ return false;
++
++ if (gfc_compare_types (&sym->ts, ts)
++ && (flavor == FL_UNKNOWN || flavor == FL_VARIABLE
++ || flavor == FL_PROCEDURE))
++ {
++ return gfc_notify_std (GFC_STD_LEGACY,
++ "Symbol '%qs' at %L already has "
++ "basic type of %s", sym->name, where,
++ gfc_basic_typename (type));
++ }
++ }
+ else
+ gfc_error ("Symbol %qs at %L already has basic type of %s", sym->name,
+ where, gfc_basic_typename (type));
+@@ -2020,8 +2039,6 @@ gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
+ return false;
+ }
+
+- flavor = sym->attr.flavor;
+-
+ if (flavor == FL_PROGRAM || flavor == FL_BLOCK_DATA || flavor == FL_MODULE
+ || flavor == FL_LABEL
+ || (flavor == FL_PROCEDURE && sym->attr.subroutine)
+diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_4.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_4.f90
+new file mode 100644
+index 00000000000..cdd29ea8846
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/duplicate_type_4.f90
+@@ -0,0 +1,13 @@
++! { dg-do compile }
++! { dg-options "-std=f95" }
++
++! PR fortran/30239
++! Check for errors when a symbol gets declared a type twice, even if it
++! is the same.
++
++INTEGER FUNCTION foo ()
++ IMPLICIT NONE
++ INTEGER :: x
++ INTEGER :: x ! { dg-error "basic type of" }
++ x = 42
++END FUNCTION foo
+diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_5.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_5.f90
+new file mode 100644
+index 00000000000..00f931809aa
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/duplicate_type_5.f90
+@@ -0,0 +1,13 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++
++program test
++ implicit none
++ integer :: x
++ integer :: x
++ x = 42
++ if (x /= 42) stop 1
++end program test
+diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_6.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_6.f90
+new file mode 100644
+index 00000000000..f0df27e323c
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/duplicate_type_6.f90
+@@ -0,0 +1,13 @@
++! { dg-do run }
++! { dg-options "-std=legacy -fdec-duplicates" }
++!
++! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++
++program test
++ implicit none
++ integer :: x
++ integer :: x
++ x = 42
++ if (x /= 42) stop 1
++end program test
+diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_7.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_7.f90
+new file mode 100644
+index 00000000000..f32472ff586
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/duplicate_type_7.f90
+@@ -0,0 +1,13 @@
++! { dg-do run }
++! { dg-options "-fdec-duplicates" }
++!
++! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++
++program test
++ implicit none
++ integer :: x
++ integer :: x! { dg-warning "Legacy Extension" }
++ x = 42
++ if (x /= 42) stop 1
++end program test
+diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_8.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_8.f90
+new file mode 100644
+index 00000000000..23c94add179
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/duplicate_type_8.f90
+@@ -0,0 +1,12 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-duplicates" }
++!
++! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++
++integer function foo ()
++ implicit none
++ integer :: x
++ integer :: x ! { dg-error "basic type of" }
++ x = 42
++end function foo
+diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_9.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_9.f90
+new file mode 100644
+index 00000000000..d5edee4d8ee
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/duplicate_type_9.f90
+@@ -0,0 +1,12 @@
++! { dg-do compile }
++! { dg-options "-fdec-duplicates -fno-dec-duplicates" }
++!
++! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++
++integer function foo ()
++ implicit none
++ integer :: x
++ integer :: x ! { dg-error "basic type of" }
++ x = 42
++end function foo
+--
+2.27.0
+
diff --git a/gcc11-fortran-fdec-ichar.patch b/gcc11-fortran-fdec-ichar.patch
new file mode 100644
index 0000000..e7b0522
--- /dev/null
+++ b/gcc11-fortran-fdec-ichar.patch
@@ -0,0 +1,78 @@
+From f883ac209b0feea860354cb4ef7ff06dc8063fab Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 12:53:35 +0000
+Subject: [PATCH 03/10] Allow more than one character as argument to ICHAR
+
+Use -fdec to enable.
+---
+ gcc/fortran/check.c | 2 +-
+ gcc/fortran/simplify.c | 4 ++--
+ .../gfortran.dg/dec_ichar_with_string_1.f | 21 +++++++++++++++++++
+ 3 files changed, 24 insertions(+), 3 deletions(-)
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_ichar_with_string_1.f
+
+diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
+index 82db8e4e1b2..623c1cc470e 100644
+--- a/gcc/fortran/check.c
++++ b/gcc/fortran/check.c
+@@ -3157,7 +3157,7 @@ gfc_check_ichar_iachar (gfc_expr *c, gfc_expr *kind)
+ else
+ return true;
+
+- if (i != 1)
++ if (i != 1 && !flag_dec)
+ {
+ gfc_error ("Argument of %s at %L must be of length one",
+ gfc_current_intrinsic, &c->where);
+diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
+index 23317a2e2d9..9900572424f 100644
+--- a/gcc/fortran/simplify.c
++++ b/gcc/fortran/simplify.c
+@@ -3261,7 +3261,7 @@ gfc_simplify_iachar (gfc_expr *e, gfc_expr *kind)
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+- if (e->value.character.length != 1)
++ if (e->value.character.length != 1 && !flag_dec)
+ {
+ gfc_error ("Argument of IACHAR at %L must be of length one", &e->where);
+ return &gfc_bad_expr;
+@@ -3459,7 +3459,7 @@ gfc_simplify_ichar (gfc_expr *e, gfc_expr *kind)
+ if (e->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+- if (e->value.character.length != 1)
++ if (e->value.character.length != 1 && !flag_dec)
+ {
+ gfc_error ("Argument of ICHAR at %L must be of length one", &e->where);
+ return &gfc_bad_expr;
+diff --git a/gcc/testsuite/gfortran.dg/dec_ichar_with_string_1.f b/gcc/testsuite/gfortran.dg/dec_ichar_with_string_1.f
+new file mode 100644
+index 00000000000..85efccecc0f
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_ichar_with_string_1.f
+@@ -0,0 +1,21 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test ICHAR and IACHAR with more than one character as argument
++!
++! Test case contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM ichar_more_than_one_character
++ CHARACTER*4 st/'Test'/
++ INTEGER i
++
++ i = ICHAR(st)
++ if (i.NE.84) STOP 1
++ i = IACHAR(st)
++ if (i.NE.84) STOP 2
++ i = ICHAR('Test')
++ if (i.NE.84) STOP 3
++ i = IACHAR('Test')
++ if (i.NE.84) STOP 4
++ END
+--
+2.27.0
+
diff --git a/gcc11-fortran-fdec-non-integer-index.patch b/gcc11-fortran-fdec-non-integer-index.patch
new file mode 100644
index 0000000..074df3b
--- /dev/null
+++ b/gcc11-fortran-fdec-non-integer-index.patch
@@ -0,0 +1,158 @@
+From 67aef262311d6a746786ee0f59748ccaa7e1e711 Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 13:09:54 +0000
+Subject: [PATCH 04/10] Allow non-integer substring indexes
+
+Use -fdec-non-integer-index compiler flag to enable. Also enabled by -fdec.
+---
+ gcc/fortran/lang.opt | 4 ++++
+ gcc/fortran/options.c | 1 +
+ gcc/fortran/resolve.c | 20 +++++++++++++++++++
+ .../dec_not_integer_substring_indexes_1.f | 18 +++++++++++++++++
+ .../dec_not_integer_substring_indexes_2.f | 18 +++++++++++++++++
+ .../dec_not_integer_substring_indexes_3.f | 18 +++++++++++++++++
+ 6 files changed, 79 insertions(+)
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_3.f
+
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index c4da248f07c..d527c106bd6 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -489,6 +489,10 @@ fdec-math
+ Fortran Var(flag_dec_math)
+ Enable legacy math intrinsics for compatibility.
+
++fdec-non-integer-index
++Fortran Var(flag_dec_non_integer_index)
++Enable support for non-integer substring indexes.
++
+ fdec-structure
+ Fortran Var(flag_dec_structure)
+ Enable support for DEC STRUCTURE/RECORD.
+diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
+index f19ba87f8a0..9a042f64881 100644
+--- a/gcc/fortran/options.c
++++ b/gcc/fortran/options.c
+@@ -78,6 +78,7 @@ set_dec_flags (int value)
+ SET_BITFLAG (flag_dec_blank_format_item, value, value);
+ SET_BITFLAG (flag_dec_char_conversions, value, value);
+ SET_BITFLAG (flag_dec_duplicates, value, value);
++ SET_BITFLAG (flag_dec_non_integer_index, value, value);
+ }
+
+ /* Finalize DEC flags. */
+diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
+index 4b90cb59902..bc0df0fdb99 100644
+--- a/gcc/fortran/resolve.c
++++ b/gcc/fortran/resolve.c
+@@ -5131,6 +5131,16 @@ gfc_resolve_substring (gfc_ref *ref, bool *equal_length)
+ if (!gfc_resolve_expr (ref->u.ss.start))
+ return false;
+
++ /* In legacy mode, allow non-integer string indexes by converting */
++ if (flag_dec_non_integer_index && ref->u.ss.start->ts.type != BT_INTEGER
++ && gfc_numeric_ts (&ref->u.ss.start->ts))
++ {
++ gfc_typespec t;
++ t.type = BT_INTEGER;
++ t.kind = ref->u.ss.start->ts.kind;
++ gfc_convert_type_warn (ref->u.ss.start, &t, 2, 1);
++ }
++
+ if (ref->u.ss.start->ts.type != BT_INTEGER)
+ {
+ gfc_error ("Substring start index at %L must be of type INTEGER",
+@@ -5160,6 +5170,16 @@ gfc_resolve_substring (gfc_ref *ref, bool *equal_length)
+ if (!gfc_resolve_expr (ref->u.ss.end))
+ return false;
+
++ /* Non-integer string index endings, as for start */
++ if (flag_dec_non_integer_index && ref->u.ss.end->ts.type != BT_INTEGER
++ && gfc_numeric_ts (&ref->u.ss.end->ts))
++ {
++ gfc_typespec t;
++ t.type = BT_INTEGER;
++ t.kind = ref->u.ss.end->ts.kind;
++ gfc_convert_type_warn (ref->u.ss.end, &t, 2, 1);
++ }
++
+ if (ref->u.ss.end->ts.type != BT_INTEGER)
+ {
+ gfc_error ("Substring end index at %L must be of type INTEGER",
+diff --git a/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_1.f b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_1.f
+new file mode 100644
+index 00000000000..0be28abaa4b
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_1.f
+@@ -0,0 +1,18 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test not integer substring indexes
++!
++! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM not_integer_substring_indexes
++ CHARACTER*5 st/'Tests'/
++ REAL ir/1.0/
++ REAL ir2/4.0/
++
++ if (st(ir:4).ne.'Test') stop 1
++ if (st(1:ir2).ne.'Test') stop 2
++ if (st(1.0:4).ne.'Test') stop 3
++ if (st(1:4.0).ne.'Test') stop 4
++ if (st(2.5:4).ne.'est') stop 5
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_2.f b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_2.f
+new file mode 100644
+index 00000000000..3cf05296d0c
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_2.f
+@@ -0,0 +1,18 @@
++! { dg-do run }
++! { dg-options "-fdec-non-integer-index" }
++!
++! Test not integer substring indexes
++!
++! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM not_integer_substring_indexes
++ CHARACTER*5 st/'Tests'/
++ REAL ir/1.0/
++ REAL ir2/4.0/
++
++ if (st(ir:4).ne.'Test') stop 1
++ if (st(1:ir2).ne.'Test') stop 2
++ if (st(1.0:4).ne.'Test') stop 3
++ if (st(1:4.0).ne.'Test') stop 4
++ if (st(2.5:4).ne.'est') stop 5
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_3.f b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_3.f
+new file mode 100644
+index 00000000000..703de995897
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_not_integer_substring_indexes_3.f
+@@ -0,0 +1,18 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-non-integer-index" }
++!
++! Test not integer substring indexes
++!
++! Test case contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM not_integer_substring_indexes
++ CHARACTER*5 st/'Tests'/
++ REAL ir/1.0/
++ REAL ir2/4.0/
++
++ if (st(ir:4).ne.'Test') stop 1 ! { dg-error "Substring start index" }
++ if (st(1:ir2).ne.'Test') stop 2 ! { dg-error "Substring end index" }
++ if (st(1.0:4).ne.'Test') stop 3 ! { dg-error "Substring start index" }
++ if (st(1:4.0).ne.'Test') stop 4 ! { dg-error "Substring end index" }
++ if (st(2.5:4).ne.'est') stop 5 ! { dg-error "Substring start index" }
++ END
+--
+2.27.0
+
diff --git a/gcc11-fortran-fdec-non-logical-if.patch b/gcc11-fortran-fdec-non-logical-if.patch
new file mode 100644
index 0000000..0133d23
--- /dev/null
+++ b/gcc11-fortran-fdec-non-logical-if.patch
@@ -0,0 +1,378 @@
+From cc87ddb841017bb0976b05091733609ee17d7f05 Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 13:15:17 +0000
+Subject: [PATCH 07/10] Allow non-logical expressions in IF statements
+
+Use -fdec-non-logical-if to enable feature. Also enabled using -fdec.
+---
+ gcc/fortran/lang.opt | 4 ++
+ gcc/fortran/options.c | 1 +
+ gcc/fortran/resolve.c | 60 ++++++++++++++++---
+ ...gical_expressions_if_statements_blocks_1.f | 25 ++++++++
+ ...gical_expressions_if_statements_blocks_2.f | 25 ++++++++
+ ...gical_expressions_if_statements_blocks_3.f | 25 ++++++++
+ ...gical_expressions_if_statements_blocks_4.f | 45 ++++++++++++++
+ ...gical_expressions_if_statements_blocks_5.f | 45 ++++++++++++++
+ ...gical_expressions_if_statements_blocks_6.f | 45 ++++++++++++++
+ 9 files changed, 266 insertions(+), 9 deletions(-)
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_3.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_4.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_5.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_6.f
+
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index 4a269ebb22d..d886c2f33ed 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -497,6 +497,10 @@ fdec-override-kind
+ Fortran Var(flag_dec_override_kind)
+ Enable support for per variable kind specification.
+
++fdec-non-logical-if
++Fortran Var(flag_dec_non_logical_if)
++Enable support for non-logical expressions in if statements.
++
+ fdec-old-init
+ Fortran Var(flag_dec_old_init)
+ Enable support for old style initializers in derived types.
+diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
+index edbab483b36..a946c86790a 100644
+--- a/gcc/fortran/options.c
++++ b/gcc/fortran/options.c
+@@ -81,6 +81,7 @@ set_dec_flags (int value)
+ SET_BITFLAG (flag_dec_non_integer_index, value, value);
+ SET_BITFLAG (flag_dec_old_init, value, value);
+ SET_BITFLAG (flag_dec_override_kind, value, value);
++ SET_BITFLAG (flag_dec_non_logical_if, value, value);
+ }
+
+ /* Finalize DEC flags. */
+diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
+index bc0df0fdb99..07dd039f3bf 100644
+--- a/gcc/fortran/resolve.c
++++ b/gcc/fortran/resolve.c
+@@ -10789,10 +10789,31 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
+ switch (b->op)
+ {
+ case EXEC_IF:
+- if (t && b->expr1 != NULL
+- && (b->expr1->ts.type != BT_LOGICAL || b->expr1->rank != 0))
+- gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
+- &b->expr1->where);
++ if (t && b->expr1 != NULL)
++ {
++ if (flag_dec_non_logical_if && b->expr1->ts.type != BT_LOGICAL)
++ {
++ gfc_expr* cast;
++ cast = gfc_ne (b->expr1,
++ gfc_get_int_expr (1, &gfc_current_locus, 0),
++ INTRINSIC_NE);
++ if (cast == NULL)
++ gfc_internal_error ("gfc_resolve_blocks(): Failed to cast "
++ "to LOGICAL in IF");
++ b->expr1 = cast;
++ if (warn_conversion_extra)
++ {
++ gfc_warning (OPT_Wconversion_extra, "Non-LOGICAL type in"
++ " IF statement condition %L will be true if"
++ " it evaluates to nonzero",
++ &b->expr1->where);
++ }
++ }
++
++ if ((b->expr1->ts.type != BT_LOGICAL || b->expr1->rank != 0))
++ gfc_error ("IF clause at %L requires a scalar LOGICAL "
++ "expression", &b->expr1->where);
++ }
+ break;
+
+ case EXEC_WHERE:
+@@ -12093,11 +12114,32 @@ start:
+ break;
+
+ case EXEC_IF:
+- if (t && code->expr1 != NULL
+- && (code->expr1->ts.type != BT_LOGICAL
+- || code->expr1->rank != 0))
+- gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
+- &code->expr1->where);
++ if (t && code->expr1 != NULL)
++ {
++ if (flag_dec_non_logical_if
++ && code->expr1->ts.type != BT_LOGICAL)
++ {
++ gfc_expr* cast;
++ cast = gfc_ne (code->expr1,
++ gfc_get_int_expr (1, &gfc_current_locus, 0),
++ INTRINSIC_NE);
++ if (cast == NULL)
++ gfc_internal_error ("gfc_resolve_code(): Failed to cast "
++ "to LOGICAL in IF");
++ code->expr1 = cast;
++ if (warn_conversion_extra)
++ {
++ gfc_warning (OPT_Wconversion_extra, "Non-LOGICAL type in"
++ " IF statement condition %L will be true if"
++ " it evaluates to nonzero",
++ &code->expr1->where);
++ }
++ }
++
++ if (code->expr1->ts.type != BT_LOGICAL || code->expr1->rank != 0)
++ gfc_error ("IF clause at %L requires a scalar LOGICAL "
++ "expression", &code->expr1->where);
++ }
+ break;
+
+ case EXEC_CALL:
+diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_1.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_1.f
+new file mode 100644
+index 00000000000..0101db893ca
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_1.f
+@@ -0,0 +1,25 @@
++! { dg-do run }
++! { dg-options "-fdec -Wconversion-extra" }
++!
++! Allow logical expressions in if statements and blocks
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM logical_exp_if_st_bl
++ INTEGER ipos/1/
++ INTEGER ineg/0/
++
++ ! Test non logical variables
++ if (ineg) STOP 1 ! { dg-warning "if it evaluates to nonzero" }
++ if (0) STOP 2 ! { dg-warning "if it evaluates to nonzero" }
++
++ ! Test non logical expressions in if statements
++ if (MOD(ipos, 1)) STOP 3 ! { dg-warning "if it evaluates to nonzero" }
++
++ ! Test non logical expressions in if blocks
++ if (MOD(2 * ipos, 2)) then ! { dg-warning "if it evaluates to nonzero" }
++ STOP 4
++ endif
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_2.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_2.f
+new file mode 100644
+index 00000000000..876f4e09508
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_2.f
+@@ -0,0 +1,25 @@
++! { dg-do run }
++! { dg-options "-fdec-non-logical-if -Wconversion-extra" }
++!
++! Allow logical expressions in if statements and blocks
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM logical_exp_if_st_bl
++ INTEGER ipos/1/
++ INTEGER ineg/0/
++
++ ! Test non logical variables
++ if (ineg) STOP 1 ! { dg-warning "if it evaluates to nonzero" }
++ if (0) STOP 2 ! { dg-warning "if it evaluates to nonzero" }
++
++ ! Test non logical expressions in if statements
++ if (MOD(ipos, 1)) STOP 3 ! { dg-warning "if it evaluates to nonzero" }
++
++ ! Test non logical expressions in if blocks
++ if (MOD(2 * ipos, 2)) then ! { dg-warning "if it evaluates to nonzero" }
++ STOP 4
++ endif
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_3.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_3.f
+new file mode 100644
+index 00000000000..35cb4c51b8d
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_3.f
+@@ -0,0 +1,25 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-non-logical-if" }
++!
++! Allow logical expressions in if statements and blocks
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM logical_exp_if_st_bl
++ INTEGER ipos/1/
++ INTEGER ineg/0/
++
++ ! Test non logical variables
++ if (ineg) STOP 1 ! { dg-error "IF clause at" }
++ if (0) STOP 2 ! { dg-error "IF clause at" }
++
++ ! Test non logical expressions in if statements
++ if (MOD(ipos, 1)) STOP 3 ! { dg-error "IF clause at" }
++
++ ! Test non logical expressions in if blocks
++ if (MOD(2 * ipos, 2)) then ! { dg-error "IF clause at" }
++ STOP 4
++ endif
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_4.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_4.f
+new file mode 100644
+index 00000000000..7b60b60827f
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_4.f
+@@ -0,0 +1,45 @@
++! { dg-do run }
++! { dg-options "-fdec -Wconversion-extra" }
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ function othersub1()
++ integer*4 othersub1
++ othersub1 = 9
++ end
++
++ function othersub2()
++ integer*4 othersub2
++ othersub2 = 0
++ end
++
++ program MAIN
++ integer*4 othersub1
++ integer*4 othersub2
++ integer a /1/
++ integer b /2/
++
++ if (othersub1()) then ! { dg-warning "if it evaluates to nonzero" }
++ write(*,*) "OK"
++ else
++ stop 1
++ end if
++ if (othersub2()) then ! { dg-warning "if it evaluates to nonzero" }
++ stop 2
++ else
++ write(*,*) "OK"
++ end if
++ if (a-b) then ! { dg-warning "if it evaluates to nonzero" }
++ write(*,*) "OK"
++ else
++ stop 3
++ end if
++ if (b-(a+1)) then ! { dg-warning "if it evaluates to nonzero" }
++ stop 3
++ else
++ write(*,*) "OK"
++ end if
++ end
++
+diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_5.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_5.f
+new file mode 100644
+index 00000000000..80336f48ca1
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_5.f
+@@ -0,0 +1,45 @@
++! { dg-do run }
++! { dg-options "-fdec-non-logical-if -Wconversion-extra" }
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ function othersub1()
++ integer*4 othersub1
++ othersub1 = 9
++ end
++
++ function othersub2()
++ integer*4 othersub2
++ othersub2 = 0
++ end
++
++ program MAIN
++ integer*4 othersub1
++ integer*4 othersub2
++ integer a /1/
++ integer b /2/
++
++ if (othersub1()) then ! { dg-warning "Non-LOGICAL type in IF statement" }
++ write(*,*) "OK"
++ else
++ stop 1
++ end if
++ if (othersub2()) then ! { dg-warning "Non-LOGICAL type in IF statement" }
++ stop 2
++ else
++ write(*,*) "OK"
++ end if
++ if (a-b) then ! { dg-warning "Non-LOGICAL type in IF statement" }
++ write(*,*) "OK"
++ else
++ stop 3
++ end if
++ if (b-(a+1)) then ! { dg-warning "Non-LOGICAL type in IF statement" }
++ stop 3
++ else
++ write(*,*) "OK"
++ end if
++ end
++
+diff --git a/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_6.f b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_6.f
+new file mode 100644
+index 00000000000..e1125ca717a
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_logical_expressions_if_statements_blocks_6.f
+@@ -0,0 +1,45 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-non-logical-if" }
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchema@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ function othersub1()
++ integer*4 othersub1
++ othersub1 = 9
++ end
++
++ function othersub2()
++ integer*4 othersub2
++ othersub2 = 0
++ end
++
++ program MAIN
++ integer*4 othersub1
++ integer*4 othersub2
++ integer a /1/
++ integer b /2/
++
++ if (othersub1()) then ! { dg-error "IF clause at" }
++ write(*,*) "OK"
++ else
++ stop 1
++ end if
++ if (othersub2()) then ! { dg-error "IF clause at" }
++ stop 2
++ else
++ write(*,*) "OK"
++ end if
++ if (a-b) then ! { dg-error "IF clause at" }
++ write(*,*) "OK"
++ else
++ stop 3
++ end if
++ if (b-(a+1)) then ! { dg-error "IF clause at" }
++ stop 3
++ else
++ write(*,*) "OK"
++ end if
++ end
++
+--
+2.27.0
+
diff --git a/gcc11-fortran-fdec-old-init.patch b/gcc11-fortran-fdec-old-init.patch
new file mode 100644
index 0000000..8554f2e
--- /dev/null
+++ b/gcc11-fortran-fdec-old-init.patch
@@ -0,0 +1,185 @@
+From 8bcc0f85ed1718c0dd9033ad4a34df181aabaffe Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 13:11:06 +0000
+Subject: [PATCH 05/10] Allow old-style initializers in derived types
+
+This allows simple declarations in derived types and structures, such as:
+ LOGICAL*1 NIL /0/
+Only single value expressions are allowed at the moment.
+
+Use -fdec-old-init to enable. Also enabled by -fdec.
+---
+ gcc/fortran/decl.c | 27 +++++++++++++++----
+ gcc/fortran/lang.opt | 4 +++
+ gcc/fortran/options.c | 1 +
+ ...ec_derived_types_initialised_old_style_1.f | 25 +++++++++++++++++
+ ...ec_derived_types_initialised_old_style_2.f | 25 +++++++++++++++++
+ ...ec_derived_types_initialised_old_style_3.f | 26 ++++++++++++++++++
+ 6 files changed, 103 insertions(+), 5 deletions(-)
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_3.f
+
+diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
+index 723915822f3..5c8c1b7981b 100644
+--- a/gcc/fortran/decl.c
++++ b/gcc/fortran/decl.c
+@@ -2827,12 +2827,29 @@ variable_decl (int elem)
+ but not components of derived types. */
+ else if (gfc_current_state () == COMP_DERIVED)
+ {
+- gfc_error ("Invalid old style initialization for derived type "
+- "component at %C");
+- m = MATCH_ERROR;
+- goto cleanup;
++ if (flag_dec_old_init)
++ {
++ /* Attempt to match an old-style initializer which is a simple
++ integer or character expression; this will not work with
++ multiple values. */
++ m = gfc_match_init_expr (&initializer);
++ if (m == MATCH_ERROR)
++ goto cleanup;
++ else if (m == MATCH_YES)
++ {
++ m = gfc_match ("/");
++ if (m != MATCH_YES)
++ goto cleanup;
++ }
++ }
++ else
++ {
++ gfc_error ("Invalid old style initialization for derived type "
++ "component at %C");
++ m = MATCH_ERROR;
++ goto cleanup;
++ }
+ }
+-
+ /* For structure components, read the initializer as a special
+ expression and let the rest of this function apply the initializer
+ as usual. */
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index d527c106bd6..25cc948699b 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -493,6 +493,10 @@ fdec-non-integer-index
+ Fortran Var(flag_dec_non_integer_index)
+ Enable support for non-integer substring indexes.
+
++fdec-old-init
++Fortran Var(flag_dec_old_init)
++Enable support for old style initializers in derived types.
++
+ fdec-structure
+ Fortran Var(flag_dec_structure)
+ Enable support for DEC STRUCTURE/RECORD.
+diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
+index 9a042f64881..d6bd36c3a8a 100644
+--- a/gcc/fortran/options.c
++++ b/gcc/fortran/options.c
+@@ -79,6 +79,7 @@ set_dec_flags (int value)
+ SET_BITFLAG (flag_dec_char_conversions, value, value);
+ SET_BITFLAG (flag_dec_duplicates, value, value);
+ SET_BITFLAG (flag_dec_non_integer_index, value, value);
++ SET_BITFLAG (flag_dec_old_init, value, value);
+ }
+
+ /* Finalize DEC flags. */
+diff --git a/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_1.f b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_1.f
+new file mode 100644
+index 00000000000..eac4f9bfcf1
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_1.f
+@@ -0,0 +1,25 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test old style initializers in derived types
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM spec_in_var
++ TYPE STRUCT1
++ INTEGER*4 ID /8/
++ INTEGER*4 TYPE /5/
++ INTEGER*8 DEFVAL /0/
++ CHARACTER*(5) NAME /'tests'/
++ LOGICAL*1 NIL /0/
++ END TYPE STRUCT1
++
++ TYPE (STRUCT1) SINST
++
++ IF(SINST%ID.NE.8) STOP 1
++ IF(SINST%TYPE.NE.5) STOP 2
++ IF(SINST%DEFVAL.NE.0) STOP 3
++ IF(SINST%NAME.NE.'tests') STOP 4
++ IF(SINST%NIL) STOP 5
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_2.f b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_2.f
+new file mode 100644
+index 00000000000..d904c8b2974
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_2.f
+@@ -0,0 +1,25 @@
++! { dg-do run }
++! { dg-options "-std=legacy -fdec-old-init" }
++!
++! Test old style initializers in derived types
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM spec_in_var
++ TYPE STRUCT1
++ INTEGER*4 ID /8/
++ INTEGER*4 TYPE /5/
++ INTEGER*8 DEFVAL /0/
++ CHARACTER*(5) NAME /'tests'/
++ LOGICAL*1 NIL /0/
++ END TYPE STRUCT1
++
++ TYPE (STRUCT1) SINST
++
++ IF(SINST%ID.NE.8) STOP 1
++ IF(SINST%TYPE.NE.5) STOP 2
++ IF(SINST%DEFVAL.NE.0) STOP 3
++ IF(SINST%NAME.NE.'tests') STOP 4
++ IF(SINST%NIL) STOP 5
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_3.f b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_3.f
+new file mode 100644
+index 00000000000..58c2b4b66cf
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_derived_types_initialised_old_style_3.f
+@@ -0,0 +1,26 @@
++! { dg-do compile }
++! { dg-options "-std=legacy -fdec -fno-dec-old-init" }
++!
++! Test old style initializers in derived types
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++
++ PROGRAM spec_in_var
++ TYPE STRUCT1
++ INTEGER*4 ID /8/ ! { dg-error "Invalid old style initialization" }
++ INTEGER*4 TYPE /5/ ! { dg-error "Invalid old style initialization" }
++ INTEGER*8 DEFVAL /0/ ! { dg-error "Invalid old style initialization" }
++ CHARACTER*(5) NAME /'tests'/ ! { dg-error "Invalid old style initialization" }
++ LOGICAL*1 NIL /0/ ! { dg-error "Invalid old style initialization" }
++ END TYPE STRUCT1
++
++ TYPE (STRUCT1) SINST
++
++ IF(SINST%ID.NE.8) STOP 1 ! { dg-error "'id' at \\(1\\) is not a member" }
++ IF(SINST%TYPE.NE.5) STOP 2 ! { dg-error "'type' at \\(1\\) is not a member" }
++ IF(SINST%DEFVAL.NE.0) STOP 3 ! { dg-error "'defval' at \\(1\\) is not a member" }
++ IF(SINST%NAME.NE.'tests') STOP 4 ! { dg-error "'name' at \\(1\\) is not a member" }
++ IF(SINST%NIL) STOP 5 ! { dg-error "'nil' at \\(1\\) is not a member" }
++ END
+--
+2.27.0
+
diff --git a/gcc11-fortran-fdec-override-kind.patch b/gcc11-fortran-fdec-override-kind.patch
new file mode 100644
index 0000000..e1c7b83
--- /dev/null
+++ b/gcc11-fortran-fdec-override-kind.patch
@@ -0,0 +1,588 @@
+From 786869fd62813e80da9b6545a295d53c36275c19 Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 13:12:14 +0000
+Subject: [PATCH 06/10] Allow string length and kind to be specified on a per
+ variable basis.
+
+This allows kind/length to be mixed with array specification in
+declarations.
+
+e.g.
+
+ INTEGER*4 x*2, y*8
+ CHARACTER names*20(10)
+ REAL v(100)*8, vv*4(50)
+
+The per-variable size overrides the kind or length specified for the type.
+
+Use -fdec-override-kind to enable. Also enabled by -fdec.
+
+Note: this feature is a merger of two previously separate features.
+
+Now accepts named constants as kind parameters:
+
+ INTEGER A
+ PARAMETER (A=2)
+ INTEGER B*(A)
+
+Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+
+Now rejects invalid kind parameters and prints error messages:
+
+ INTEGER X*3
+
+caused an internal compiler error.
+
+Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+---
+ gcc/fortran/decl.c | 156 ++++++++++++++----
+ gcc/fortran/lang.opt | 4 +
+ gcc/fortran/options.c | 1 +
+ .../dec_mixed_char_array_declaration_1.f | 13 ++
+ .../dec_mixed_char_array_declaration_2.f | 13 ++
+ .../dec_mixed_char_array_declaration_3.f | 13 ++
+ .../gfortran.dg/dec_spec_in_variable_1.f | 31 ++++
+ .../gfortran.dg/dec_spec_in_variable_2.f | 31 ++++
+ .../gfortran.dg/dec_spec_in_variable_3.f | 31 ++++
+ .../gfortran.dg/dec_spec_in_variable_4.f | 14 ++
+ .../gfortran.dg/dec_spec_in_variable_5.f | 19 +++
+ .../gfortran.dg/dec_spec_in_variable_6.f | 19 +++
+ .../gfortran.dg/dec_spec_in_variable_7.f | 15 ++
+ .../gfortran.dg/dec_spec_in_variable_8.f | 14 ++
+ 14 files changed, 340 insertions(+), 34 deletions(-)
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_3.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_3.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_4.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_5.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_6.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_7.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_spec_in_variable_8.f
+
+diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
+index 5c8c1b7981b..f7dc9d8263d 100644
+--- a/gcc/fortran/decl.c
++++ b/gcc/fortran/decl.c
+@@ -1213,6 +1213,54 @@ syntax:
+ return MATCH_ERROR;
+ }
+
++/* This matches the nonstandard kind given after a variable name, like:
++ INTEGER x*2, y*4
++ The per-variable kind will override any kind given in the type
++ declaration.
++*/
++
++static match
++match_per_symbol_kind (int *length)
++{
++ match m;
++ gfc_expr *expr = NULL;
++
++ m = gfc_match_char ('*');
++ if (m != MATCH_YES)
++ return m;
++
++ m = gfc_match_small_literal_int (length, NULL);
++ if (m == MATCH_YES || m == MATCH_ERROR)
++ return m;
++
++ if (gfc_match_char ('(') == MATCH_NO)
++ return MATCH_ERROR;
++
++ m = gfc_match_expr (&expr);
++ if (m == MATCH_YES)
++ {
++ m = MATCH_ERROR; // Assume error
++ if (gfc_expr_check_typed (expr, gfc_current_ns, false))
++ {
++ if ((expr->expr_type == EXPR_CONSTANT)
++ && (expr->ts.type == BT_INTEGER))
++ {
++ *length = mpz_get_si(expr->value.integer);
++ m = MATCH_YES;
++ }
++ }
++
++ if (m == MATCH_YES)
++ {
++ if (gfc_match_char (')') == MATCH_NO)
++ m = MATCH_ERROR;
++ }
++ }
++
++ if (expr != NULL)
++ gfc_free_expr (expr);
++ return m;
++}
+
+ /* Special subroutine for finding a symbol. Check if the name is found
+ in the current name space. If not, and we're compiling a function or
+@@ -2443,6 +2491,35 @@ check_function_name (char *name)
+ }
+
+
++static match
++match_character_length_clause (gfc_charlen **cl, bool *cl_deferred, int elem)
++{
++ gfc_expr* char_len;
++ char_len = NULL;
++
++ match m = match_char_length (&char_len, cl_deferred, false);
++ if (m == MATCH_YES)
++ {
++ *cl = gfc_new_charlen (gfc_current_ns, NULL);
++ (*cl)->length = char_len;
++ }
++ else if (m == MATCH_NO)
++ {
++ if (elem > 1
++ && (current_ts.u.cl->length == NULL
++ || current_ts.u.cl->length->expr_type != EXPR_CONSTANT))
++ {
++ *cl = gfc_new_charlen (gfc_current_ns, NULL);
++ (*cl)->length = gfc_copy_expr (current_ts.u.cl->length);
++ }
++ else
++ *cl = current_ts.u.cl;
++
++ *cl_deferred = current_ts.deferred;
++ }
++ return m;
++}
++
+ /* Match a variable name with an optional initializer. When this
+ subroutine is called, a variable is expected to be parsed next.
+ Depending on what is happening at the moment, updates either the
+@@ -2453,7 +2530,7 @@ variable_decl (int elem)
+ {
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ static unsigned int fill_id = 0;
+- gfc_expr *initializer, *char_len;
++ gfc_expr *initializer;
+ gfc_array_spec *as;
+ gfc_array_spec *cp_as; /* Extra copy for Cray Pointees. */
+ gfc_charlen *cl;
+@@ -2462,11 +2539,15 @@ variable_decl (int elem)
+ match m;
+ bool t;
+ gfc_symbol *sym;
++ match cl_match;
++ match kind_match;
++ int overridden_kind;
+ char c;
+
+ initializer = NULL;
+ as = NULL;
+ cp_as = NULL;
++ kind_match = MATCH_NO;
+
+ /* When we get here, we've just matched a list of attributes and
+ maybe a type and a double colon. The next thing we expect to see
+@@ -2519,6 +2600,28 @@ variable_decl (int elem)
+
+ var_locus = gfc_current_locus;
+
++
++ cl = NULL;
++ cl_deferred = false;
++ cl_match = MATCH_NO;
++
++ /* Check for a character length clause before an array clause */
++ if (flag_dec_override_kind)
++ {
++ if (current_ts.type == BT_CHARACTER)
++ {
++ cl_match = match_character_length_clause (&cl, &cl_deferred, elem);
++ if (cl_match == MATCH_ERROR)
++ goto cleanup;
++ }
++ else
++ {
++ kind_match = match_per_symbol_kind (&overridden_kind);
++ if (kind_match == MATCH_ERROR)
++ goto cleanup;
++ }
++ }
++
+ /* Now we could see the optional array spec. or character length. */
+ m = gfc_match_array_spec (&as, true, true);
+ if (m == MATCH_ERROR)
+@@ -2667,40 +2770,12 @@ variable_decl (int elem)
+ }
+ }
+
+- char_len = NULL;
+- cl = NULL;
+- cl_deferred = false;
+-
+- if (current_ts.type == BT_CHARACTER)
++ /* Second chance for a character length clause */
++ if (cl_match == MATCH_NO && current_ts.type == BT_CHARACTER)
+ {
+- switch (match_char_length (&char_len, &cl_deferred, false))
+- {
+- case MATCH_YES:
+- cl = gfc_new_charlen (gfc_current_ns, NULL);
+-
+- cl->length = char_len;
+- break;
+-
+- /* Non-constant lengths need to be copied after the first
+- element. Also copy assumed lengths. */
+- case MATCH_NO:
+- if (elem > 1
+- && (current_ts.u.cl->length == NULL
+- || current_ts.u.cl->length->expr_type != EXPR_CONSTANT))
+- {
+- cl = gfc_new_charlen (gfc_current_ns, NULL);
+- cl->length = gfc_copy_expr (current_ts.u.cl->length);
+- }
+- else
+- cl = current_ts.u.cl;
+-
+- cl_deferred = current_ts.deferred;
+-
+- break;
+-
+- case MATCH_ERROR:
+- goto cleanup;
+- }
++ m = match_character_length_clause (&cl, &cl_deferred, elem);
++ if (m == MATCH_ERROR)
++ goto cleanup;
+ }
+
+ /* The dummy arguments and result of the abreviated form of MODULE
+@@ -2802,6 +2877,19 @@ variable_decl (int elem)
+ goto cleanup;
+ }
+
++ if (kind_match == MATCH_YES)
++ {
++ gfc_find_symbol (name, gfc_current_ns, 1, &sym);
++ /* sym *must* be found at this point */
++ sym->ts.kind = overridden_kind;
++ if (gfc_validate_kind (sym->ts.type, sym->ts.kind, true) < 0)
++ {
++ gfc_error ("Kind %d not supported for type %s at %C",
++ sym->ts.kind, gfc_basic_typename (sym->ts.type));
++ return MATCH_ERROR;
++ }
++ }
++
+ if (!check_function_name (name))
+ {
+ m = MATCH_ERROR;
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index 25cc948699b..4a269ebb22d 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -493,6 +493,10 @@ fdec-non-integer-index
+ Fortran Var(flag_dec_non_integer_index)
+ Enable support for non-integer substring indexes.
+
++fdec-override-kind
++Fortran Var(flag_dec_override_kind)
++Enable support for per variable kind specification.
++
+ fdec-old-init
+ Fortran Var(flag_dec_old_init)
+ Enable support for old style initializers in derived types.
+diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
+index d6bd36c3a8a..edbab483b36 100644
+--- a/gcc/fortran/options.c
++++ b/gcc/fortran/options.c
+@@ -80,6 +80,7 @@ set_dec_flags (int value)
+ SET_BITFLAG (flag_dec_duplicates, value, value);
+ SET_BITFLAG (flag_dec_non_integer_index, value, value);
+ SET_BITFLAG (flag_dec_old_init, value, value);
++ SET_BITFLAG (flag_dec_override_kind, value, value);
+ }
+
+ /* Finalize DEC flags. */
+diff --git a/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_1.f b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_1.f
+new file mode 100644
+index 00000000000..706ea4112a4
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_1.f
+@@ -0,0 +1,13 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test character declaration with mixed string length and array specification
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM character_declaration
++ CHARACTER ASPEC_SLENGTH*2 (5) /'01','02','03','04','05'/
++ CHARACTER SLENGTH_ASPEC(5)*2 /'01','02','03','04','05'/
++ if (ASPEC_SLENGTH(3).NE.SLENGTH_ASPEC(3)) STOP 1
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_2.f b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_2.f
+new file mode 100644
+index 00000000000..26d2acf01de
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_2.f
+@@ -0,0 +1,13 @@
++! { dg-do run }
++! { dg-options "-fdec-override-kind" }
++!
++! Test character declaration with mixed string length and array specification
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM character_declaration
++ CHARACTER ASPEC_SLENGTH*2 (5) /'01','02','03','04','05'/
++ CHARACTER SLENGTH_ASPEC(5)*2 /'01','02','03','04','05'/
++ if (ASPEC_SLENGTH(3).NE.SLENGTH_ASPEC(3)) STOP 1
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_3.f b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_3.f
+new file mode 100644
+index 00000000000..76e4f0bdb93
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_mixed_char_array_declaration_3.f
+@@ -0,0 +1,13 @@
++! { dg-do compile }
++! { dg-options "-fdec-override-kind -fno-dec-override-kind" }
++!
++! Test character declaration with mixed string length and array specification
++!
++! Contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM character_declaration
++ CHARACTER ASPEC_SLENGTH*2 (5) /'01','02','03','04','05'/ ! { dg-error "Syntax error" }
++ CHARACTER SLENGTH_ASPEC(5)*2 /'01','02','03','04','05'/
++ if (ASPEC_SLENGTH(3).NE.SLENGTH_ASPEC(3)) STOP 1 ! { dg-error " Operands of comparison operator" }
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_1.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_1.f
+new file mode 100644
+index 00000000000..edd0f5874b7
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_1.f
+@@ -0,0 +1,31 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test kind specification in variable not in type
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program spec_in_var
++ integer*8 ai*1, bi*4, ci
++ real*4 ar*4, br*8, cr
++
++ ai = 1
++ ar = 1.0
++ bi = 2
++ br = 2.0
++ ci = 3
++ cr = 3.0
++
++ if (ai .ne. 1) stop 1
++ if (abs(ar - 1.0) > 1.0D-6) stop 2
++ if (bi .ne. 2) stop 3
++ if (abs(br - 2.0) > 1.0D-6) stop 4
++ if (ci .ne. 3) stop 5
++ if (abs(cr - 3.0) > 1.0D-6) stop 6
++ if (kind(ai) .ne. 1) stop 7
++ if (kind(ar) .ne. 4) stop 8
++ if (kind(bi) .ne. 4) stop 9
++ if (kind(br) .ne. 8) stop 10
++ if (kind(ci) .ne. 8) stop 11
++ if (kind(cr) .ne. 4) stop 12
++ end
+diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_2.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_2.f
+new file mode 100644
+index 00000000000..bfaba584dbb
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_2.f
+@@ -0,0 +1,31 @@
++! { dg-do run }
++! { dg-options "-fdec-override-kind" }
++!
++! Test kind specification in variable not in type
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program spec_in_var
++ integer*8 ai*1, bi*4, ci
++ real*4 ar*4, br*8, cr
++
++ ai = 1
++ ar = 1.0
++ bi = 2
++ br = 2.0
++ ci = 3
++ cr = 3.0
++
++ if (ai .ne. 1) stop 1
++ if (abs(ar - 1.0) > 1.0D-6) stop 2
++ if (bi .ne. 2) stop 3
++ if (abs(br - 2.0) > 1.0D-6) stop 4
++ if (ci .ne. 3) stop 5
++ if (abs(cr - 3.0) > 1.0D-6) stop 6
++ if (kind(ai) .ne. 1) stop 7
++ if (kind(ar) .ne. 4) stop 8
++ if (kind(bi) .ne. 4) stop 9
++ if (kind(br) .ne. 8) stop 10
++ if (kind(ci) .ne. 8) stop 11
++ if (kind(cr) .ne. 4) stop 12
++ end
+diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_3.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_3.f
+new file mode 100644
+index 00000000000..5ff434e7466
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_3.f
+@@ -0,0 +1,31 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-override-kind" }
++!
++! Test kind specification in variable not in type
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program spec_in_var
++ integer*8 ai*1, bi*4, ci ! { dg-error "Syntax error" }
++ real*4 ar*4, br*8, cr ! { dg-error "Syntax error" }
++
++ ai = 1
++ ar = 1.0
++ bi = 2
++ br = 2.0
++ ci = 3
++ cr = 3.0
++
++ if (ai .ne. 1) stop 1
++ if (abs(ar - 1.0) > 1.0D-6) stop 2
++ if (bi .ne. 2) stop 3
++ if (abs(br - 2.0) > 1.0D-6) stop 4
++ if (ci .ne. 3) stop 5
++ if (abs(cr - 3.0) > 1.0D-6) stop 6
++ if (kind(ai) .ne. 1) stop 7
++ if (kind(ar) .ne. 4) stop 8
++ if (kind(bi) .ne. 4) stop 9
++ if (kind(br) .ne. 8) stop 10
++ if (kind(ci) .ne. 8) stop 11
++ if (kind(cr) .ne. 4) stop 12
++ end
+diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_4.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_4.f
+new file mode 100644
+index 00000000000..c01980e8b9d
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_4.f
+@@ -0,0 +1,14 @@
++! { dg-do compile }
++!
++! Test kind specification in variable not in type. The per variable
++! kind specification is not enabled so these should fail
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program spec_in_var
++ integer a
++ parameter(a=2)
++ integer b*(a) ! { dg-error "Syntax error" }
++ real c*(8) ! { dg-error "Syntax error" }
++ logical d*1_1 ! { dg-error "Syntax error" }
++ end
+diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_5.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_5.f
+new file mode 100644
+index 00000000000..e2f39da3f4f
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_5.f
+@@ -0,0 +1,19 @@
++! { dg-do run }
++! { dg-options "-fdec-override-kind" }
++!
++! Test kind specification in variable not in type
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program spec_in_var
++ integer a
++ parameter(a=2)
++ integer b*(a)
++ real c*(8)
++ logical d*(1_1)
++ character e*(a)
++ if (kind(b).ne.2) stop 1
++ if (kind(c).ne.8) stop 2
++ if (kind(d).ne.1) stop 3
++ if (len(e).ne.2) stop 4
++ end
+diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_6.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_6.f
+new file mode 100644
+index 00000000000..569747874e3
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_6.f
+@@ -0,0 +1,19 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test kind specification in variable not in type
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program spec_in_var
++ integer a
++ parameter(a=2)
++ integer b*(a)
++ real c*(8)
++ logical d*(1_1)
++ character e*(a)
++ if (kind(b).ne.2) stop 1
++ if (kind(c).ne.8) stop 2
++ if (kind(d).ne.1) stop 3
++ if (len(e).ne.2) stop 4
++ end
+diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_7.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_7.f
+new file mode 100644
+index 00000000000..b975bfd15c5
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_7.f
+@@ -0,0 +1,15 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-override-kind" }
++!
++! Test kind specification in variable not in type as the per variable
++! kind specification is not enables these should fail
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program spec_in_var
++ integer a
++ parameter(a=2)
++ integer b*(a) ! { dg-error "Syntax error" }
++ real c*(8) ! { dg-error "Syntax error" }
++ logical d*1_1 ! { dg-error "Syntax error" }
++ end
+diff --git a/gcc/testsuite/gfortran.dg/dec_spec_in_variable_8.f b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_8.f
+new file mode 100644
+index 00000000000..85732e0bd85
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_spec_in_variable_8.f
+@@ -0,0 +1,14 @@
++! { dg-do compile }
++! { dg-options "-fdec" }
++!
++! Check that invalid kind values are rejected.
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program spec_in_var
++ integer a
++ parameter(a=3)
++ integer b*(a) ! { dg-error "Kind 3 not supported" }
++ real c*(78) ! { dg-error "Kind 78 not supported" }
++ logical d*(*) ! { dg-error "Invalid character" }
++ end
+--
+2.27.0
+
diff --git a/gcc11-fortran-fdec-promotion.patch b/gcc11-fortran-fdec-promotion.patch
new file mode 100644
index 0000000..8643405
--- /dev/null
+++ b/gcc11-fortran-fdec-promotion.patch
@@ -0,0 +1,2093 @@
+From 7a27318818e359a277f2fa5f7dc3932d0fb950f5 Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 14:58:07 +0000
+Subject: [PATCH 08/10] Support type promotion in calls to intrinsics
+
+Use -fdec-promotion or -fdec to enable this feature.
+
+Merged 2 commits: worked on by Ben Brewer <ben.brewer@codethink.co.uk>,
+Francisco Redondo Marchena <francisco.marchena@codethink.co.uk> and
+Jeff Law <law@redhat.com>
+
+Re-worked by Mark Eggleston <mark.eggleston@codethink.com>
+---
+ gcc/fortran/check.c | 71 +++++-
+ gcc/fortran/intrinsic.c | 5 +
+ gcc/fortran/iresolve.c | 91 ++++---
+ gcc/fortran/lang.opt | 4 +
+ gcc/fortran/options.c | 1 +
+ gcc/fortran/simplify.c | 240 ++++++++++++++----
+ ...trinsic_int_real_array_const_promotion_1.f | 18 ++
+ ...trinsic_int_real_array_const_promotion_2.f | 18 ++
+ ...trinsic_int_real_array_const_promotion_3.f | 18 ++
+ ...dec_intrinsic_int_real_const_promotion_1.f | 90 +++++++
+ ...dec_intrinsic_int_real_const_promotion_2.f | 90 +++++++
+ ...dec_intrinsic_int_real_const_promotion_3.f | 92 +++++++
+ .../dec_intrinsic_int_real_promotion_1.f | 130 ++++++++++
+ .../dec_intrinsic_int_real_promotion_2.f | 130 ++++++++++
+ .../dec_intrinsic_int_real_promotion_3.f | 130 ++++++++++
+ .../dec_intrinsic_int_real_promotion_4.f | 118 +++++++++
+ .../dec_intrinsic_int_real_promotion_5.f | 118 +++++++++
+ .../dec_intrinsic_int_real_promotion_6.f | 118 +++++++++
+ .../dec_intrinsic_int_real_promotion_7.f | 118 +++++++++
+ .../gfortran.dg/dec_kind_promotion-1.f | 40 +++
+ .../gfortran.dg/dec_kind_promotion-2.f | 40 +++
+ .../gfortran.dg/dec_kind_promotion-3.f | 39 +++
+ 22 files changed, 1639 insertions(+), 80 deletions(-)
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
+
+diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
+index 623c1cc470e..e20a834a860 100644
+--- a/gcc/fortran/check.c
++++ b/gcc/fortran/check.c
+@@ -1396,12 +1396,40 @@ gfc_check_allocated (gfc_expr *array)
+ }
+
+
++/* Check function where both arguments must be real or integer
++ and warn if they are different types. */
++
++bool
++check_int_real_promotion (gfc_expr *a, gfc_expr *b)
++{
++ gfc_expr *i;
++
++ if (!int_or_real_check (a, 0))
++ return false;
++
++ if (!int_or_real_check (b, 1))
++ return false;
++
++ if (a->ts.type != b->ts.type)
++ {
++ i = (a->ts.type != BT_REAL ? a : b);
++ gfc_warning_now (OPT_Wconversion, "Conversion from INTEGER to REAL "
++ "at %L might lose precision", &i->where);
++ }
++
++ return true;
++}
++
++
+ /* Common check function where the first argument must be real or
+ integer and the second argument must be the same as the first. */
+
+ bool
+ gfc_check_a_p (gfc_expr *a, gfc_expr *p)
+ {
++ if (flag_dec_promotion)
++ return check_int_real_promotion (a, p);
++
+ if (!int_or_real_check (a, 0))
+ return false;
+
+@@ -3724,6 +3752,41 @@ check_rest (bt type, int kind, gfc_actual_arglist *arglist)
+ }
+
+
++/* Check function where all arguments of an argument list must be real
++ or integer. */
++
++static bool
++check_rest_int_real (gfc_actual_arglist *arglist)
++{
++ gfc_actual_arglist *arg, *tmp;
++ gfc_expr *x;
++ int m, n;
++
++ if (!min_max_args (arglist))
++ return false;
++
++ for (arg = arglist, n=1; arg; arg = arg->next, n++)
++ {
++ x = arg->expr;
++ if (x->ts.type != BT_INTEGER && x->ts.type != BT_REAL)
++ {
++ gfc_error ("%<a%d%> argument of %qs intrinsic at %L must be "
++ "INTEGER or REAL", n, gfc_current_intrinsic, &x->where);
++ return false;
++ }
++
++ for (tmp = arglist, m=1; tmp != arg; tmp = tmp->next, m++)
++ if (!gfc_check_conformance (tmp->expr, x,
++ "arguments 'a%d' and 'a%d' for "
++ "intrinsic '%s'", m, n,
++ gfc_current_intrinsic))
++ return false;
++ }
++
++ return true;
++}
++
++
+ bool
+ gfc_check_min_max (gfc_actual_arglist *arg)
+ {
+@@ -3748,7 +3811,10 @@ gfc_check_min_max (gfc_actual_arglist *arg)
+ return false;
+ }
+
+- return check_rest (x->ts.type, x->ts.kind, arg);
++ if (flag_dec_promotion && x->ts.type != BT_CHARACTER)
++ return check_rest_int_real (arg);
++ else
++ return check_rest (x->ts.type, x->ts.kind, arg);
+ }
+
+
+@@ -5121,6 +5187,9 @@ gfc_check_shift (gfc_expr *i, gfc_expr *shift)
+ bool
+ gfc_check_sign (gfc_expr *a, gfc_expr *b)
+ {
++ if (flag_dec_promotion)
++ return check_int_real_promotion (a, b);
++
+ if (!int_or_real_check (a, 0))
+ return false;
+
+diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
+index e68eff8bdbb..81b3a24c2be 100644
+--- a/gcc/fortran/intrinsic.c
++++ b/gcc/fortran/intrinsic.c
+@@ -4467,6 +4467,11 @@ check_arglist (gfc_actual_arglist **ap, gfc_intrinsic_sym *sym,
+ if (ts.kind == 0)
+ ts.kind = actual->expr->ts.kind;
+
++ /* If kind promotion is allowed don't check for kind if it is smaller */
++ if (flag_dec_promotion && ts.type == BT_INTEGER)
++ if (actual->expr->ts.kind < ts.kind)
++ ts.kind = actual->expr->ts.kind;
++
+ if (!gfc_compare_types (&ts, &actual->expr->ts))
+ {
+ if (error_flag)
+diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
+index e17fe45f080..b9cdaff2499 100644
+--- a/gcc/fortran/iresolve.c
++++ b/gcc/fortran/iresolve.c
+@@ -817,19 +817,22 @@ gfc_resolve_dble (gfc_expr *f, gfc_expr *a)
+ void
+ gfc_resolve_dim (gfc_expr *f, gfc_expr *a, gfc_expr *p)
+ {
+- f->ts.type = a->ts.type;
+ if (p != NULL)
+- f->ts.kind = gfc_kind_max (a,p);
+- else
+- f->ts.kind = a->ts.kind;
+-
+- if (p != NULL && a->ts.kind != p->ts.kind)
+ {
+- if (a->ts.kind == gfc_kind_max (a,p))
+- gfc_convert_type (p, &a->ts, 2);
++ f->ts.kind = gfc_kind_max (a,p);
++ if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
++ f->ts.type = BT_REAL;
+ else
+- gfc_convert_type (a, &p->ts, 2);
++ f->ts.type = BT_INTEGER;
++
++ if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
++ gfc_convert_type (a, &f->ts, 2);
++
++ if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
++ gfc_convert_type (p, &f->ts, 2);
+ }
++ else
++ f->ts = a->ts;
+
+ f->value.function.name
+ = gfc_get_string ("__dim_%c%d", gfc_type_letter (f->ts.type), f->ts.kind);
+@@ -1606,14 +1609,17 @@ gfc_resolve_minmax (const char *name, gfc_expr *f, gfc_actual_arglist *args)
+ /* Find the largest type kind. */
+ for (a = args->next; a; a = a->next)
+ {
++ if (a->expr-> ts.type == BT_REAL)
++ f->ts.type = BT_REAL;
++
+ if (a->expr->ts.kind > f->ts.kind)
+ f->ts.kind = a->expr->ts.kind;
+ }
+
+- /* Convert all parameters to the required kind. */
++ /* Convert all parameters to the required type and/or kind. */
+ for (a = args; a; a = a->next)
+ {
+- if (a->expr->ts.kind != f->ts.kind)
++ if (a->expr->ts.type != f->ts.type || a->expr->ts.kind != f->ts.kind)
+ gfc_convert_type (a->expr, &f->ts, 2);
+ }
+
+@@ -2106,19 +2112,22 @@ gfc_resolve_minval (gfc_expr *f, gfc_expr *array, gfc_expr *dim,
+ void
+ gfc_resolve_mod (gfc_expr *f, gfc_expr *a, gfc_expr *p)
+ {
+- f->ts.type = a->ts.type;
+ if (p != NULL)
+- f->ts.kind = gfc_kind_max (a,p);
+- else
+- f->ts.kind = a->ts.kind;
+-
+- if (p != NULL && a->ts.kind != p->ts.kind)
+ {
+- if (a->ts.kind == gfc_kind_max (a,p))
+- gfc_convert_type (p, &a->ts, 2);
++ f->ts.kind = gfc_kind_max (a,p);
++ if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
++ f->ts.type = BT_REAL;
+ else
+- gfc_convert_type (a, &p->ts, 2);
++ f->ts.type = BT_INTEGER;
++
++ if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
++ gfc_convert_type (a, &f->ts, 2);
++
++ if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
++ gfc_convert_type (p, &f->ts, 2);
+ }
++ else
++ f->ts = a->ts;
+
+ f->value.function.name
+ = gfc_get_string ("__mod_%c%d", gfc_type_letter (f->ts.type), f->ts.kind);
+@@ -2128,19 +2137,22 @@ gfc_resolve_mod (gfc_expr *f, gfc_expr *a, gfc_expr *p)
+ void
+ gfc_resolve_modulo (gfc_expr *f, gfc_expr *a, gfc_expr *p)
+ {
+- f->ts.type = a->ts.type;
+ if (p != NULL)
+- f->ts.kind = gfc_kind_max (a,p);
+- else
+- f->ts.kind = a->ts.kind;
+-
+- if (p != NULL && a->ts.kind != p->ts.kind)
+ {
+- if (a->ts.kind == gfc_kind_max (a,p))
+- gfc_convert_type (p, &a->ts, 2);
++ f->ts.kind = gfc_kind_max (a,p);
++ if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
++ f->ts.type = BT_REAL;
+ else
+- gfc_convert_type (a, &p->ts, 2);
++ f->ts.type = BT_INTEGER;
++
++ if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
++ gfc_convert_type (a, &f->ts, 2);
++
++ if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
++ gfc_convert_type (p, &f->ts, 2);
+ }
++ else
++ f->ts = a->ts;
+
+ f->value.function.name
+ = gfc_get_string ("__modulo_%c%d", gfc_type_letter (f->ts.type),
+@@ -2515,9 +2527,26 @@ gfc_resolve_shift (gfc_expr *f, gfc_expr *i, gfc_expr *shift ATTRIBUTE_UNUSED)
+
+
+ void
+-gfc_resolve_sign (gfc_expr *f, gfc_expr *a, gfc_expr *b ATTRIBUTE_UNUSED)
++gfc_resolve_sign (gfc_expr *f, gfc_expr *a, gfc_expr *b)
+ {
+- f->ts = a->ts;
++ if (b != NULL)
++ {
++ f->ts.kind = gfc_kind_max (a, b);
++ if (a->ts.type == BT_REAL || b->ts.type == BT_REAL)
++ f->ts.type = BT_REAL;
++ else
++ f->ts.type = BT_INTEGER;
++
++ if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
++ gfc_convert_type (a, &f->ts, 2);
++
++ if (b->ts.kind != f->ts.kind || b->ts.type != f->ts.type)
++ gfc_convert_type (b, &f->ts, 2);
++ }
++ else
++ {
++ f->ts = a->ts;
++ }
+ f->value.function.name
+ = gfc_get_string ("__sign_%c%d", gfc_type_letter (a->ts.type), a->ts.kind);
+ }
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index d886c2f33ed..4ca2f93f2df 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -505,6 +505,10 @@ fdec-old-init
+ Fortran Var(flag_dec_old_init)
+ Enable support for old style initializers in derived types.
+
++fdec-promotion
++Fortran Var(flag_dec_promotion)
++Add support for type promotion in intrinsic arguments
++
+ fdec-structure
+ Fortran Var(flag_dec_structure)
+ Enable support for DEC STRUCTURE/RECORD.
+diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
+index a946c86790a..15079c7e95a 100644
+--- a/gcc/fortran/options.c
++++ b/gcc/fortran/options.c
+@@ -82,6 +82,7 @@ set_dec_flags (int value)
+ SET_BITFLAG (flag_dec_old_init, value, value);
+ SET_BITFLAG (flag_dec_override_kind, value, value);
+ SET_BITFLAG (flag_dec_non_logical_if, value, value);
++ SET_BITFLAG (flag_dec_promotion, value, value);
+ }
+
+ /* Finalize DEC flags. */
+diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
+index 9900572424f..3419e06fec2 100644
+--- a/gcc/fortran/simplify.c
++++ b/gcc/fortran/simplify.c
+@@ -2333,39 +2333,79 @@ gfc_simplify_digits (gfc_expr *x)
+ }
+
+
++/* Simplify function which sets the floating-point value of ar from
++ the value of a independently if a is integer of real. */
++
++static void
++simplify_int_real_promotion (const gfc_expr *a, const gfc_expr *b, mpfr_t *ar)
++{
++ if (a->ts.type == BT_REAL)
++ {
++ mpfr_init2 (*ar, (a->ts.kind * 8));
++ mpfr_set (*ar, a->value.real, GFC_RND_MODE);
++ }
++ else
++ {
++ mpfr_init2 (*ar, (b->ts.kind * 8));
++ mpfr_set_z (*ar, a->value.integer, GFC_RND_MODE);
++ }
++}
++
++
++/* Simplify function which promotes a and b arguments from integer to real if
++ required in ar and br floating-point values. This function returns true if
++ a or b are reals and false otherwise. */
++
++static bool
++simplify_int_real_promotion2 (const gfc_expr *a, const gfc_expr *b, mpfr_t *ar,
++ mpfr_t *br)
++{
++ if (a->ts.type != BT_REAL && b->ts.type != BT_REAL)
++ return false;
++
++ simplify_int_real_promotion (a, b, ar);
++ simplify_int_real_promotion (b, a, br);
++
++ return true;
++}
++
++
+ gfc_expr *
+ gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
+ {
+ gfc_expr *result;
+ int kind;
+
++ mpfr_t xr;
++ mpfr_t yr;
++
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+- kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
+- result = gfc_get_constant_expr (x->ts.type, kind, &x->where);
+-
+- switch (x->ts.type)
++ if ((x->ts.type != BT_REAL && x->ts.type != BT_INTEGER)
++ || (y->ts.type != BT_REAL && y->ts.type != BT_INTEGER))
+ {
+- case BT_INTEGER:
+- if (mpz_cmp (x->value.integer, y->value.integer) > 0)
+- mpz_sub (result->value.integer, x->value.integer, y->value.integer);
+- else
+- mpz_set_ui (result->value.integer, 0);
+-
+- break;
+-
+- case BT_REAL:
+- if (mpfr_cmp (x->value.real, y->value.real) > 0)
+- mpfr_sub (result->value.real, x->value.real, y->value.real,
+- GFC_RND_MODE);
+- else
+- mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
++ gfc_internal_error ("gfc_simplify_dim(): Bad arguments");
++ return NULL;
++ }
+
+- break;
++ kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
+
+- default:
+- gfc_internal_error ("gfc_simplify_dim(): Bad type");
++ if (simplify_int_real_promotion2 (x, y, &xr, &yr))
++ {
++ result = gfc_get_constant_expr (BT_REAL, kind, &x->where);
++ if (mpfr_cmp (xr, yr) > 0)
++ mpfr_sub (result->value.real, xr, yr, GFC_RND_MODE);
++ else
++ mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
++ }
++ else
++ {
++ result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
++ if (mpz_cmp (x->value.integer, y->value.integer) > 0)
++ mpz_sub (result->value.integer, x->value.integer, y->value.integer);
++ else
++ mpz_set_ui (result->value.integer, 0);
+ }
+
+ return range_check (result, "DIM");
+@@ -4953,6 +4993,76 @@ min_max_choose (gfc_expr *arg, gfc_expr *extremum, int sign, bool back_val)
+ {
+ int ret;
+
++ mpfr_t *arp;
++ mpfr_t *erp;
++ mpfr_t ar;
++ mpfr_t er;
++
++ if (arg->ts.type != extremum->ts.type)
++ {
++ if (arg->ts.type == BT_REAL)
++ {
++ arp = &arg->value.real;
++ }
++ else
++ {
++ mpfr_init2 (ar, (arg->ts.kind * 8));
++ mpfr_set_z (ar, arg->value.integer, GFC_RND_MODE);
++ arp = &ar;
++ }
++
++ if (extremum->ts.type == BT_REAL)
++ {
++ erp = &extremum->value.real;
++ }
++ else
++ {
++ mpfr_init2 (er, (extremum->ts.kind * 8));
++ mpfr_set_z (er, extremum->value.integer, GFC_RND_MODE);
++ erp = &er;
++ }
++
++ if (mpfr_nan_p (*erp))
++ {
++ ret = 1;
++ extremum->ts.type = arg->ts.type;
++ extremum->ts.kind = arg->ts.kind;
++ if (arg->ts.type == BT_INTEGER)
++ {
++ mpz_init2 (extremum->value.integer, (arg->ts.kind * 8));
++ mpz_set (extremum->value.integer, arg->value.integer);
++ }
++ else
++ {
++ mpfr_init2 (extremum->value.real, (arg->ts.kind * 8));
++ mpfr_set (extremum->value.real, *arp, GFC_RND_MODE);
++ }
++ }
++ else if (mpfr_nan_p (*arp))
++ ret = -1;
++ else
++ {
++ ret = mpfr_cmp (*arp, *erp) * sign;
++ if (ret > 0)
++ {
++ extremum->ts.type = arg->ts.type;
++ extremum->ts.kind = arg->ts.kind;
++ if (arg->ts.type == BT_INTEGER)
++ {
++ mpz_init2 (extremum->value.integer, (arg->ts.kind * 8));
++ mpz_set (extremum->value.integer, arg->value.integer);
++ }
++ else
++ {
++ mpfr_init2 (extremum->value.real, (arg->ts.kind * 8));
++ mpfr_set (extremum->value.real, *arp, GFC_RND_MODE);
++ }
++ }
++ }
++
++ return ret;
++ }
++
+ switch (arg->ts.type)
+ {
+ case BT_INTEGER:
+@@ -5912,7 +6022,9 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
+ gfc_expr *result;
+ int kind;
+
+- /* First check p. */
++ mpfr_t ar;
++ mpfr_t pr;
++
+ if (p->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+@@ -5942,16 +6054,24 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
+ if (a->expr_type != EXPR_CONSTANT)
+ return NULL;
+
++ if (a->ts.type != BT_REAL && a->ts.type != BT_INTEGER)
++ {
++ gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
++ return NULL;
++ }
++
+ kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
+- result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
+
+- if (a->ts.type == BT_INTEGER)
+- mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
+- else
++ if (simplify_int_real_promotion2 (a, p, &ar, &pr))
+ {
++ result = gfc_get_constant_expr (BT_REAL, kind, &a->where);
+ gfc_set_model_kind (kind);
+- mpfr_fmod (result->value.real, a->value.real, p->value.real,
+- GFC_RND_MODE);
++ mpfr_fmod (result->value.real, ar, pr, GFC_RND_MODE);
++ }
++ else
++ {
++ result = gfc_get_constant_expr (BT_INTEGER, kind, &a->where);
++ mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
+ }
+
+ return range_check (result, "MOD");
+@@ -5964,7 +6084,9 @@ gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
+ gfc_expr *result;
+ int kind;
+
+- /* First check p. */
++ mpfr_t ar;
++ mpfr_t pr;
++
+ if (p->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+@@ -5991,28 +6113,36 @@ gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
+ gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
+ }
+
++ if (a->ts.type != BT_REAL && a->ts.type != BT_INTEGER)
++ {
++ gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
++ return NULL;
++ }
++
+ if (a->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
+- result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
+
+- if (a->ts.type == BT_INTEGER)
+- mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
+- else
++ if (simplify_int_real_promotion2 (a, p, &ar, &pr))
+ {
++ result = gfc_get_constant_expr (BT_REAL, kind, &a->where);
+ gfc_set_model_kind (kind);
+- mpfr_fmod (result->value.real, a->value.real, p->value.real,
+- GFC_RND_MODE);
++ mpfr_fmod (result->value.real, ar, pr, GFC_RND_MODE);
+ if (mpfr_cmp_ui (result->value.real, 0) != 0)
+- {
+- if (mpfr_signbit (a->value.real) != mpfr_signbit (p->value.real))
+- mpfr_add (result->value.real, result->value.real, p->value.real,
+- GFC_RND_MODE);
+- }
+- else
+- mpfr_copysign (result->value.real, result->value.real,
+- p->value.real, GFC_RND_MODE);
++ {
++ if (mpfr_signbit (ar) != mpfr_signbit (pr))
++ mpfr_add (result->value.real, result->value.real, pr,
++ GFC_RND_MODE);
++ }
++ else
++ mpfr_copysign (result->value.real, result->value.real, pr,
++ GFC_RND_MODE);
++ }
++ else
++ {
++ result = gfc_get_constant_expr (BT_INTEGER, kind, &a->where);
++ mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
+ }
+
+ return range_check (result, "MODULO");
+@@ -7578,27 +7708,41 @@ gfc_expr *
+ gfc_simplify_sign (gfc_expr *x, gfc_expr *y)
+ {
+ gfc_expr *result;
++ bool neg;
+
+ if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
+
++ switch (y->ts.type)
++ {
++ case BT_INTEGER:
++ neg = (mpz_sgn (y->value.integer) < 0);
++ break;
++
++ case BT_REAL:
++ neg = (mpfr_sgn (y->value.real) < 0);
++ break;
++
++ default:
++ gfc_internal_error ("Bad type in gfc_simplify_sign");
++ }
++
+ switch (x->ts.type)
+ {
+ case BT_INTEGER:
+ mpz_abs (result->value.integer, x->value.integer);
+- if (mpz_sgn (y->value.integer) < 0)
++ if (neg)
+ mpz_neg (result->value.integer, result->value.integer);
+ break;
+
+ case BT_REAL:
+- if (flag_sign_zero)
++ if (flag_sign_zero && y->ts.type == BT_REAL)
+ mpfr_copysign (result->value.real, x->value.real, y->value.real,
+- GFC_RND_MODE);
++ GFC_RND_MODE);
+ else
+- mpfr_setsign (result->value.real, x->value.real,
+- mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
++ mpfr_setsign (result->value.real, x->value.real, neg, GFC_RND_MODE);
+ break;
+
+ default:
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
+new file mode 100644
+index 00000000000..25763852139
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
+@@ -0,0 +1,18 @@
++! { dg-do compile }
++! { dg-options "-fdec" }
++!
++! Test promotion between integers and reals for mod and modulo where
++! A is a constant array and P is zero.
++!
++! Compilation errors are expected
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program promotion_int_real_array_const
++ real a(2) = mod([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
++ a = mod([12.0, 34.0], 0)*4 ! { dg-error "shall not be zero" }
++ real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
++ b = modulo([12.0, 34.0], 0)*4 ! { dg-error "shall not be zero" }
++ end program
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
+new file mode 100644
+index 00000000000..b78a46054f4
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
+@@ -0,0 +1,18 @@
++! { dg-do compile }
++! { dg-options "-fdec-promotion" }
++!
++! Test promotion between integers and reals for mod and modulo where
++! A is a constant array and P is zero.
++!
++! Compilation errors are expected
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program promotion_int_real_array_const
++ real a(2) = mod([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
++ a = mod([12.0, 34.0], 0)*4 ! { dg-error "shall not be zero" }
++ real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
++ b = modulo([12.0, 34.0], 0)*4 ! { dg-error "shall not be zero" }
++ end program
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
+new file mode 100644
+index 00000000000..318ab5db97e
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
+@@ -0,0 +1,18 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-promotion" }
++!
++! Test promotion between integers and reals for mod and modulo where
++! A is a constant array and P is zero.
++!
++! Compilation errors are expected
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program promotion_int_real_array_const
++ real a(2) = mod([12, 34], 0.0)*4 ! { dg-error "'a' and 'p' arguments of 'mod'" }
++ a = mod([12.0, 34.0], 0)*4 ! { dg-error "'a' and 'p' arguments of 'mod'" }
++ real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "'a' and 'p' arguments of 'modulo'" }
++ b = modulo([12.0, 34.0], 0)*4 ! { dg-error "'a' and 'p' arguments of 'modulo'" }
++ end program
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
+new file mode 100644
+index 00000000000..27eb2582bb2
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
+@@ -0,0 +1,90 @@
++! { dg-do run }
++! { dg-options "-fdec -finit-real=snan" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real_const
++ ! array_nan 4th position value is NAN
++ REAL array_nan(4)
++ DATA array_nan(1)/-4.0/
++ DATA array_nan(2)/3.0/
++ DATA array_nan(3)/-2/
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ m_i = MOD(4, 3)
++ if (m_i .ne. 1) STOP 1
++ m_r = MOD(4.0, 3.0)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 2
++ m_r = MOD(4, 3.0)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(4.0, 3)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++
++ md_i = MODULO(4, 3)
++ if (md_i .ne. 1) STOP 5
++ md_r = MODULO(4.0, 3.0)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 6
++ md_r = MODULO(4, 3.0)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 7
++ md_r = MODULO(4.0, 3)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 8
++
++ d_i = DIM(4, 3)
++ if (d_i .ne. 1) STOP 9
++ d_r = DIM(4.0, 3.0)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 10
++ d_r = DIM(4.0, 3)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 11
++ d_r = DIM(3, 4.0)
++ if (abs(d_r) > 1.0D-6) STOP 12
++
++ s_i = SIGN(-4, 3)
++ if (s_i .ne. 4) STOP 13
++ s_r = SIGN(4.0, -3.0)
++ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
++ s_r = SIGN(4.0, -3)
++ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
++ s_r = SIGN(-4, 3.0)
++ if (abs(s_r - 4.0) > 1.0D-6) STOP 16
++
++ mx_i = MAX(-4, -3, 2, 1)
++ if (mx_i .ne. 2) STOP 17
++ mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
++ if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
++ mx_r = MAX(-4, -3.0, 2.0, 1)
++ if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
++ mx_i = MAXLOC(array_nan, 1)
++ if (mx_i .ne. 2) STOP 20
++
++ mn_i = MIN(-4, -3, 2, 1)
++ if (mn_i .ne. -4) STOP 21
++ mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
++ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
++ mn_r = MIN(-4, -3.0, 2.0, 1)
++ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
++ mn_i = MINLOC(array_nan, 1)
++ if (mn_i .ne. 1) STOP 24
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
+new file mode 100644
+index 00000000000..bdd017b7280
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
+@@ -0,0 +1,90 @@
++! { dg-do run }
++! { dg-options "-fdec-promotion -finit-real=snan" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real_const
++ ! array_nan 4th position value is NAN
++ REAL array_nan(4)
++ DATA array_nan(1)/-4.0/
++ DATA array_nan(2)/3.0/
++ DATA array_nan(3)/-2/
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ m_i = MOD(4, 3)
++ if (m_i .ne. 1) STOP 1
++ m_r = MOD(4.0, 3.0)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 2
++ m_r = MOD(4, 3.0)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(4.0, 3)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++
++ md_i = MODULO(4, 3)
++ if (md_i .ne. 1) STOP 5
++ md_r = MODULO(4.0, 3.0)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 6
++ md_r = MODULO(4, 3.0)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 7
++ md_r = MODULO(4.0, 3)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 8
++
++ d_i = DIM(4, 3)
++ if (d_i .ne. 1) STOP 9
++ d_r = DIM(4.0, 3.0)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 10
++ d_r = DIM(4.0, 3)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 11
++ d_r = DIM(3, 4.0)
++ if (abs(d_r) > 1.0D-6) STOP 12
++
++ s_i = SIGN(-4, 3)
++ if (s_i .ne. 4) STOP 13
++ s_r = SIGN(4.0, -3.0)
++ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
++ s_r = SIGN(4.0, -3)
++ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
++ s_r = SIGN(-4, 3.0)
++ if (abs(s_r - 4.0) > 1.0D-6) STOP 16
++
++ mx_i = MAX(-4, -3, 2, 1)
++ if (mx_i .ne. 2) STOP 17
++ mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
++ if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
++ mx_r = MAX(-4, -3.0, 2.0, 1)
++ if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
++ mx_i = MAXLOC(array_nan, 1)
++ if (mx_i .ne. 2) STOP 20
++
++ mn_i = MIN(-4, -3, 2, 1)
++ if (mn_i .ne. -4) STOP 21
++ mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
++ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
++ mn_r = MIN(-4, -3.0, 2.0, 1)
++ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
++ mn_i = MINLOC(array_nan, 1)
++ if (mn_i .ne. 1) STOP 24
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
+new file mode 100644
+index 00000000000..ce90a5667d6
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
+@@ -0,0 +1,92 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-promotion -finit-real=snan" }
++!
++! Test that there is no promotion between integers and reals in
++! intrinsic operations.
++!
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real_const
++ ! array_nan 4th position value is NAN
++ REAL array_nan(4)
++ DATA array_nan(1)/-4.0/
++ DATA array_nan(2)/3.0/
++ DATA array_nan(3)/-2/
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ m_i = MOD(4, 3)
++ if (m_i .ne. 1) STOP 1
++ m_r = MOD(4.0, 3.0)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 2
++ m_r = MOD(4, 3.0) ! { dg-error "'a' and 'p' arguments" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(4.0, 3) ! { dg-error "'a' and 'p' arguments" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++
++ md_i = MODULO(4, 3)
++ if (md_i .ne. 1) STOP 5
++ md_r = MODULO(4.0, 3.0)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 6
++ md_r = MODULO(4, 3.0) ! { dg-error "'a' and 'p' arguments" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 7
++ md_r = MODULO(4.0, 3) ! { dg-error "'a' and 'p' arguments" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 8
++
++ d_i = DIM(4, 3)
++ if (d_i .ne. 1) STOP 9
++ d_r = DIM(4.0, 3.0)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 10
++ d_r = DIM(4.0, 3) ! { dg-error "'x' and 'y' arguments" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 11
++ d_r = DIM(3, 4.0) ! { dg-error "'x' and 'y' arguments" }
++ if (abs(d_r) > 1.0D-6) STOP 12
++
++ s_i = SIGN(-4, 3)
++ if (s_i .ne. 4) STOP 13
++ s_r = SIGN(4.0, -3.0)
++ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
++ s_r = SIGN(4.0, -3) ! { dg-error "'b' argument" }
++ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
++ s_r = SIGN(-4, 3.0) ! { dg-error "'b' argument" }
++ if (abs(s_r - 4.0) > 1.0D-6) STOP 16
++
++ mx_i = MAX(-4, -3, 2, 1)
++ if (mx_i .ne. 2) STOP 17
++ mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
++ if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
++ mx_r = MAX(-4, -3.0, 2.0, 1) ! { dg-error "'a2' argument" }
++ if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
++ mx_i = MAXLOC(array_nan, 1)
++ if (mx_i .ne. 2) STOP 20
++
++ mn_i = MIN(-4, -3, 2, 1)
++ if (mn_i .ne. -4) STOP 21
++ mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
++ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
++ mn_r = MIN(-4, -3.0, 2.0, 1) ! { dg-error "'a2' argument" }
++ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
++ mn_i = MINLOC(array_nan, 1)
++ if (mn_i .ne. 1) STOP 24
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
+new file mode 100644
+index 00000000000..5c2cd931a4b
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
+@@ -0,0 +1,130 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real
++ REAL l/0.0/
++ INTEGER a_i/4/
++ INTEGER*4 a2_i/4/
++ INTEGER b_i/3/
++ INTEGER*8 b2_i/3/
++ INTEGER x_i/2/
++ INTEGER y_i/1/
++ REAL a_r/4.0/
++ REAL*4 a2_r/4.0/
++ REAL b_r/3.0/
++ REAL*8 b2_r/3.0/
++ REAL x_r/2.0/
++ REAL y_r/1.0/
++
++ REAL array_nan(4)
++ DATA array_nan(1)/-4.0/
++ DATA array_nan(2)/3.0/
++ DATA array_nan(3)/-2/
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ ! array_nan 4th position value is NAN
++ array_nan(4) = 0/l
++
++ m_i = MOD(a_i, b_i)
++ if (m_i .ne. 1) STOP 1
++ m_i = MOD(a2_i, b2_i)
++ if (m_i .ne. 1) STOP 2
++ m_r = MOD(a_r, b_r)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(a2_r, b2_r)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++ m_r = MOD(a_i, b_r)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
++ m_r = MOD(a_r, b_i)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
++
++ md_i = MODULO(a_i, b_i)
++ if (md_i .ne. 1) STOP 7
++ md_i = MODULO(a2_i, b2_i)
++ if (md_i .ne. 1) STOP 8
++ md_r = MODULO(a_r, b_r)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
++ md_r = MODULO(a2_r, b2_r)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
++ md_r = MODULO(a_i, b_r)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
++ md_r = MODULO(a_r, b_i)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
++
++ d_i = DIM(a_i, b_i)
++ if (d_i .ne. 1) STOP 13
++ d_i = DIM(a2_i, b2_i)
++ if (d_i .ne. 1) STOP 14
++ d_r = DIM(a_r, b_r)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
++ d_r = DIM(a2_r, b2_r)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
++ d_r = DIM(a_r, b_i)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
++ d_r = DIM(b_i, a_r)
++ if (abs(d_r) > 1.0D-6) STOP 18
++
++ s_i = SIGN(-a_i, b_i)
++ if (s_i .ne. 4) STOP 19
++ s_i = SIGN(-a2_i, b2_i)
++ if (s_i .ne. 4) STOP 20
++ s_r = SIGN(a_r, -b_r)
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
++ s_r = SIGN(a2_r, -b2_r)
++ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
++ s_r = SIGN(a_r, -b_i)
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
++ s_r = SIGN(-a_i, b_r)
++ if (abs(s_r - a_r) > 1.0D-6) STOP 24
++
++ mx_i = MAX(-a_i, -b_i, x_i, y_i)
++ if (mx_i .ne. x_i) STOP 25
++ mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
++ if (mx_i .ne. x_i) STOP 26
++ mx_r = MAX(-a_r, -b_r, x_r, y_r)
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
++ mx_r = MAX(-a_r, -b_r, x_r, y_r)
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
++ mx_r = MAX(-a_i, -b_r, x_r, y_i)
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
++ mx_i = MAXLOC(array_nan, 1)
++ if (mx_i .ne. 2) STOP 30
++
++ mn_i = MIN(-a_i, -b_i, x_i, y_i)
++ if (mn_i .ne. -a_i) STOP 31
++ mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
++ if (mn_i .ne. -a2_i) STOP 32
++ mn_r = MIN(-a_r, -b_r, x_r, y_r)
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
++ mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
++ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
++ mn_r = MIN(-a_i, -b_r, x_r, y_i)
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
++ mn_i = MINLOC(array_nan, 1)
++ if (mn_i .ne. 1) STOP 36
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
+new file mode 100644
+index 00000000000..d64d468f7d1
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
+@@ -0,0 +1,130 @@
++! { dg-do run }
++! { dg-options "-fdec-promotion" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real
++ REAL l/0.0/
++ INTEGER a_i/4/
++ INTEGER*4 a2_i/4/
++ INTEGER b_i/3/
++ INTEGER*8 b2_i/3/
++ INTEGER x_i/2/
++ INTEGER y_i/1/
++ REAL a_r/4.0/
++ REAL*4 a2_r/4.0/
++ REAL b_r/3.0/
++ REAL*8 b2_r/3.0/
++ REAL x_r/2.0/
++ REAL y_r/1.0/
++
++ REAL array_nan(4)
++ DATA array_nan(1)/-4.0/
++ DATA array_nan(2)/3.0/
++ DATA array_nan(3)/-2/
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ ! array_nan 4th position value is NAN
++ array_nan(4) = 0/l
++
++ m_i = MOD(a_i, b_i)
++ if (m_i .ne. 1) STOP 1
++ m_i = MOD(a2_i, b2_i)
++ if (m_i .ne. 1) STOP 2
++ m_r = MOD(a_r, b_r)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(a2_r, b2_r)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++ m_r = MOD(a_i, b_r)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
++ m_r = MOD(a_r, b_i)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
++
++ md_i = MODULO(a_i, b_i)
++ if (md_i .ne. 1) STOP 7
++ md_i = MODULO(a2_i, b2_i)
++ if (md_i .ne. 1) STOP 8
++ md_r = MODULO(a_r, b_r)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
++ md_r = MODULO(a2_r, b2_r)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
++ md_r = MODULO(a_i, b_r)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
++ md_r = MODULO(a_r, b_i)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
++
++ d_i = DIM(a_i, b_i)
++ if (d_i .ne. 1) STOP 13
++ d_i = DIM(a2_i, b2_i)
++ if (d_i .ne. 1) STOP 14
++ d_r = DIM(a_r, b_r)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
++ d_r = DIM(a2_r, b2_r)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
++ d_r = DIM(a_r, b_i)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
++ d_r = DIM(b_i, a_r)
++ if (abs(d_r) > 1.0D-6) STOP 18
++
++ s_i = SIGN(-a_i, b_i)
++ if (s_i .ne. 4) STOP 19
++ s_i = SIGN(-a2_i, b2_i)
++ if (s_i .ne. 4) STOP 20
++ s_r = SIGN(a_r, -b_r)
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
++ s_r = SIGN(a2_r, -b2_r)
++ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
++ s_r = SIGN(a_r, -b_i)
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
++ s_r = SIGN(-a_i, b_r)
++ if (abs(s_r - a_r) > 1.0D-6) STOP 24
++
++ mx_i = MAX(-a_i, -b_i, x_i, y_i)
++ if (mx_i .ne. x_i) STOP 25
++ mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
++ if (mx_i .ne. x_i) STOP 26
++ mx_r = MAX(-a_r, -b_r, x_r, y_r)
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
++ mx_r = MAX(-a_r, -b_r, x_r, y_r)
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
++ mx_r = MAX(-a_i, -b_r, x_r, y_i)
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
++ mx_i = MAXLOC(array_nan, 1)
++ if (mx_i .ne. 2) STOP 30
++
++ mn_i = MIN(-a_i, -b_i, x_i, y_i)
++ if (mn_i .ne. -a_i) STOP 31
++ mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
++ if (mn_i .ne. -a2_i) STOP 32
++ mn_r = MIN(-a_r, -b_r, x_r, y_r)
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
++ mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
++ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
++ mn_r = MIN(-a_i, -b_r, x_r, y_i)
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
++ mn_i = MINLOC(array_nan, 1)
++ if (mn_i .ne. 1) STOP 36
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
+new file mode 100644
+index 00000000000..0708b666633
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
+@@ -0,0 +1,130 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-promotion" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real
++ REAL l/0.0/
++ INTEGER a_i/4/
++ INTEGER*4 a2_i/4/
++ INTEGER b_i/3/
++ INTEGER*8 b2_i/3/
++ INTEGER x_i/2/
++ INTEGER y_i/1/
++ REAL a_r/4.0/
++ REAL*4 a2_r/4.0/
++ REAL b_r/3.0/
++ REAL*8 b2_r/3.0/
++ REAL x_r/2.0/
++ REAL y_r/1.0/
++
++ REAL array_nan(4)
++ DATA array_nan(1)/-4.0/
++ DATA array_nan(2)/3.0/
++ DATA array_nan(3)/-2/
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ ! array_nan 4th position value is NAN
++ array_nan(4) = 0/l
++
++ m_i = MOD(a_i, b_i)
++ if (m_i .ne. 1) STOP 1
++ m_i = MOD(a2_i, b2_i)
++ if (m_i .ne. 1) STOP 2
++ m_r = MOD(a_r, b_r)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(a2_r, b2_r)
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++ m_r = MOD(a_i, b_r) ! { dg-error "'a' and 'p' arguments" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
++ m_r = MOD(a_r, b_i) ! { dg-error "'a' and 'p' arguments" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
++
++ md_i = MODULO(a_i, b_i)
++ if (md_i .ne. 1) STOP 7
++ md_i = MODULO(a2_i, b2_i)
++ if (md_i .ne. 1) STOP 8
++ md_r = MODULO(a_r, b_r)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
++ md_r = MODULO(a2_r, b2_r)
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
++ md_r = MODULO(a_i, b_r) ! { dg-error "'a' and 'p' arguments" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
++ md_r = MODULO(a_r, b_i) ! { dg-error "'a' and 'p' arguments" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
++
++ d_i = DIM(a_i, b_i)
++ if (d_i .ne. 1) STOP 13
++ d_i = DIM(a2_i, b2_i)
++ if (d_i .ne. 1) STOP 14
++ d_r = DIM(a_r, b_r)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
++ d_r = DIM(a2_r, b2_r)
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
++ d_r = DIM(a_r, b_i) ! { dg-error "'x' and 'y' arguments" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
++ d_r = DIM(b_i, a_r) ! { dg-error "'x' and 'y' arguments" }
++ if (abs(d_r) > 1.0D-6) STOP 18
++
++ s_i = SIGN(-a_i, b_i)
++ if (s_i .ne. 4) STOP 19
++ s_i = SIGN(-a2_i, b2_i) ! { dg-error "'b' argument" }
++ if (s_i .ne. 4) STOP 20
++ s_r = SIGN(a_r, -b_r)
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
++ s_r = SIGN(a2_r, -b2_r) ! { dg-error "'b' argument" }
++ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
++ s_r = SIGN(a_r, -b_i) ! { dg-error "'b' argument" }
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
++ s_r = SIGN(-a_i, b_r) ! { dg-error "'b' argument" }
++ if (abs(s_r - a_r) > 1.0D-6) STOP 24
++
++ mx_i = MAX(-a_i, -b_i, x_i, y_i)
++ if (mx_i .ne. x_i) STOP 25
++ mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
++ if (mx_i .ne. x_i) STOP 26
++ mx_r = MAX(-a_r, -b_r, x_r, y_r)
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
++ mx_r = MAX(-a_r, -b_r, x_r, y_r)
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
++ mx_r = MAX(-a_i, -b_r, x_r, y_i) ! { dg-error "'a2' argument" }
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
++ mx_i = MAXLOC(array_nan, 1)
++ if (mx_i .ne. 2) STOP 30
++
++ mn_i = MIN(-a_i, -b_i, x_i, y_i)
++ if (mn_i .ne. -a_i) STOP 31
++ mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
++ if (mn_i .ne. -a2_i) STOP 32
++ mn_r = MIN(-a_r, -b_r, x_r, y_r)
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
++ mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
++ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
++ mn_r = MIN(-a_i, -b_r, x_r, y_i) ! { dg-error "'a2' argument" }
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
++ mn_i = MINLOC(array_nan, 1)
++ if (mn_i .ne. 1) STOP 36
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
+new file mode 100644
+index 00000000000..efa4f236410
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
+@@ -0,0 +1,118 @@
++! { dg-do compile }
++! { dg-options "-fdec" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real
++ REAL l/0.0/
++ LOGICAL a_l
++ LOGICAL*4 a2_l
++ LOGICAL b_l
++ LOGICAL*8 b2_l
++ LOGICAL x_l
++ LOGICAL y_l
++ CHARACTER a_c
++ CHARACTER*4 a2_c
++ CHARACTER b_c
++ CHARACTER*8 b2_c
++ CHARACTER x_c
++ CHARACTER y_c
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ m_i = MOD(a_l, b_l) ! { dg-error "" }
++ if (m_i .ne. 1) STOP 1
++ m_i = MOD(a2_l, b2_l) ! { dg-error "" }
++ if (m_i .ne. 1) STOP 2
++ m_r = MOD(a_c, b_c) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(a2_c, b2_c) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++ m_r = MOD(a_l, b_c) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
++ m_r = MOD(a_c, b_l) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
++
++ md_i = MODULO(a_l, b_l) ! { dg-error "" }
++ if (md_i .ne. 1) STOP 7
++ md_i = MODULO(a2_l, b2_l) ! { dg-error "" }
++ if (md_i .ne. 1) STOP 8
++ md_r = MODULO(a_c, b_c) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
++ md_r = MODULO(a2_c, b2_c) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
++ md_r = MODULO(a_l, b_c) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
++ md_r = MODULO(a_c, b_l) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
++
++ d_i = DIM(a_l, b_l) ! { dg-error "" }
++ if (d_i .ne. 1) STOP 13
++ d_i = DIM(a2_l, b2_l) ! { dg-error "" }
++ if (d_i .ne. 1) STOP 14
++ d_r = DIM(a_c, b_c) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
++ d_r = DIM(a2_c, b2_c) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
++ d_r = DIM(a_c, b_l) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
++ d_r = DIM(b_l, a_c) ! { dg-error "" }
++ if (abs(d_r) > 1.0D-6) STOP 18
++
++ s_i = SIGN(-a_l, b_l) ! { dg-error "" }
++ if (s_i .ne. 4) STOP 19
++ s_i = SIGN(-a2_l, b2_l) ! { dg-error "" }
++ if (s_i .ne. 4) STOP 20
++ s_r = SIGN(a_c, -b_c) ! { dg-error "" }
++ if (abs(s_r - (-a_c)) > 1.0D-6) STOP 21 ! { dg-error "" }
++ s_r = SIGN(a2_c, -b2_c) ! { dg-error "" }
++ if (abs(s_r - (-a2_c)) > 1.0D-6) STOP 22 ! { dg-error "" }
++ s_r = SIGN(a_c, -b_l) ! { dg-error "" }
++ if (abs(s_r - (-a_c)) > 1.0D-6) STOP 23 ! { dg-error "" }
++ s_r = SIGN(-a_l, b_c) ! { dg-error "" }
++ if (abs(s_r - a_c) > 1.0D-6) STOP 24 ! { dg-error "" }
++
++ mx_i = MAX(-a_l, -b_l, x_l, y_l) ! { dg-error "" }
++ if (mx_i .ne. x_l) STOP 25 ! { dg-error "" }
++ mx_i = MAX(-a2_l, -b2_l, x_l, y_l) ! { dg-error "" }
++ if (mx_i .ne. x_l) STOP 26 ! { dg-error "" }
++ mx_r = MAX(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
++ if (abs(mx_r - x_c) > 1.0D-6) STOP 27 ! { dg-error "" }
++ mx_r = MAX(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
++ if (abs(mx_r - x_c) > 1.0D-6) STOP 28 ! { dg-error "" }
++ mx_r = MAX(-a_l, -b_c, x_c, y_l) ! { dg-error "" }
++ if (abs(mx_r - x_c) > 1.0D-6) STOP 29 ! { dg-error "" }
++
++ mn_i = MIN(-a_l, -b_l, x_l, y_l) ! { dg-error "" }
++ if (mn_i .ne. -a_l) STOP 31 ! { dg-error "" }
++ mn_i = MIN(-a2_l, -b2_l, x_l, y_l) ! { dg-error "" }
++ if (mn_i .ne. -a2_l) STOP 32 ! { dg-error "" }
++ mn_r = MIN(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
++ if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 33 ! { dg-error "" }
++ mn_r = MIN(-a2_c, -b2_c, x_c, y_c) ! { dg-error "" }
++ if (abs(mn_r - (-a2_c)) > 1.0D-6) STOP 34 ! { dg-error "" }
++ mn_r = MIN(-a_l, -b_c, x_c, y_l) ! { dg-error "" }
++ if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 35 ! { dg-error "" }
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
+new file mode 100644
+index 00000000000..d023af5086d
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
+@@ -0,0 +1,118 @@
++! { dg-do compile }
++! { dg-options "-fdec-promotion" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real
++ REAL l/0.0/
++ LOGICAL a_l
++ LOGICAL*4 a2_l
++ LOGICAL b_l
++ LOGICAL*8 b2_l
++ LOGICAL x_l
++ LOGICAL y_l
++ CHARACTER a_c
++ CHARACTER*4 a2_c
++ CHARACTER b_c
++ CHARACTER*8 b2_c
++ CHARACTER x_c
++ CHARACTER y_c
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ m_i = MOD(a_l, b_l) ! { dg-error "" }
++ if (m_i .ne. 1) STOP 1
++ m_i = MOD(a2_l, b2_l) ! { dg-error "" }
++ if (m_i .ne. 1) STOP 2
++ m_r = MOD(a_c, b_c) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(a2_c, b2_c) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++ m_r = MOD(a_l, b_c) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
++ m_r = MOD(a_c, b_l) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
++
++ md_i = MODULO(a_l, b_l) ! { dg-error "" }
++ if (md_i .ne. 1) STOP 7
++ md_i = MODULO(a2_l, b2_l) ! { dg-error "" }
++ if (md_i .ne. 1) STOP 8
++ md_r = MODULO(a_c, b_c) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
++ md_r = MODULO(a2_c, b2_c) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
++ md_r = MODULO(a_l, b_c) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
++ md_r = MODULO(a_c, b_l) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
++
++ d_i = DIM(a_l, b_l) ! { dg-error "" }
++ if (d_i .ne. 1) STOP 13
++ d_i = DIM(a2_l, b2_l) ! { dg-error "" }
++ if (d_i .ne. 1) STOP 14
++ d_r = DIM(a_c, b_c) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
++ d_r = DIM(a2_c, b2_c) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
++ d_r = DIM(a_c, b_l) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
++ d_r = DIM(b_l, a_c) ! { dg-error "" }
++ if (abs(d_r) > 1.0D-6) STOP 18
++
++ s_i = SIGN(-a_l, b_l) ! { dg-error "" }
++ if (s_i .ne. 4) STOP 19
++ s_i = SIGN(-a2_l, b2_l) ! { dg-error "" }
++ if (s_i .ne. 4) STOP 20
++ s_r = SIGN(a_c, -b_c) ! { dg-error "" }
++ if (abs(s_r - (-a_c)) > 1.0D-6) STOP 21 ! { dg-error "" }
++ s_r = SIGN(a2_c, -b2_c) ! { dg-error "" }
++ if (abs(s_r - (-a2_c)) > 1.0D-6) STOP 22 ! { dg-error "" }
++ s_r = SIGN(a_c, -b_l) ! { dg-error "" }
++ if (abs(s_r - (-a_c)) > 1.0D-6) STOP 23 ! { dg-error "" }
++ s_r = SIGN(-a_l, b_c) ! { dg-error "" }
++ if (abs(s_r - a_c) > 1.0D-6) STOP 24 ! { dg-error "" }
++
++ mx_i = MAX(-a_l, -b_l, x_l, y_l) ! { dg-error "" }
++ if (mx_i .ne. x_l) STOP 25 ! { dg-error "" }
++ mx_i = MAX(-a2_l, -b2_l, x_l, y_l) ! { dg-error "" }
++ if (mx_i .ne. x_l) STOP 26 ! { dg-error "" }
++ mx_r = MAX(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
++ if (abs(mx_r - x_c) > 1.0D-6) STOP 27 ! { dg-error "" }
++ mx_r = MAX(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
++ if (abs(mx_r - x_c) > 1.0D-6) STOP 28 ! { dg-error "" }
++ mx_r = MAX(-a_l, -b_c, x_c, y_l) ! { dg-error "" }
++ if (abs(mx_r - x_c) > 1.0D-6) STOP 29 ! { dg-error "" }
++
++ mn_i = MIN(-a_l, -b_l, x_l, y_l) ! { dg-error "" }
++ if (mn_i .ne. -a_l) STOP 31 ! { dg-error "" }
++ mn_i = MIN(-a2_l, -b2_l, x_l, y_l) ! { dg-error "" }
++ if (mn_i .ne. -a2_l) STOP 32 ! { dg-error "" }
++ mn_r = MIN(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
++ if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 33 ! { dg-error "" }
++ mn_r = MIN(-a2_c, -b2_c, x_c, y_c) ! { dg-error "" }
++ if (abs(mn_r - (-a2_c)) > 1.0D-6) STOP 34 ! { dg-error "" }
++ mn_r = MIN(-a_l, -b_c, x_c, y_l) ! { dg-error "" }
++ if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 35 ! { dg-error "" }
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
+new file mode 100644
+index 00000000000..00f8fb88f1b
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
+@@ -0,0 +1,118 @@
++! { dg-do compile }
++! { dg-options "-fdec" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real
++ REAL l/0.0/
++ INTEGER a_i/4/
++ INTEGER*4 a2_i/4/
++ CHARACTER b_c
++ CHARACTER*8 b2_c
++ INTEGER x_i/2/
++ CHARACTER y_c
++ REAL a_r/4.0/
++ REAL*4 a2_r/4.0/
++ LOGICAL b_l
++ LOGICAL*8 b2_l
++ REAL x_r/2.0/
++ LOGICAL y_l
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ m_i = MOD(a_i, b_c) ! { dg-error "" }
++ if (m_i .ne. 1) STOP 1
++ m_i = MOD(a2_i, b2_c) ! { dg-error "" }
++ if (m_i .ne. 1) STOP 2
++ m_r = MOD(a_r, b_l) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(a2_r, b2_l) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++ m_r = MOD(a_i, b_l) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
++ m_r = MOD(a_r, b_c) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
++
++ md_i = MODULO(a_i, b_c) ! { dg-error "" }
++ if (md_i .ne. 1) STOP 7
++ md_i = MODULO(a2_i, b2_c) ! { dg-error "" }
++ if (md_i .ne. 1) STOP 8
++ md_r = MODULO(a_r, b_l) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
++ md_r = MODULO(a2_r, b2_l) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
++ md_r = MODULO(a_i, b_l) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
++ md_r = MODULO(a_r, b_c) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
++
++ d_i = DIM(a_i, b_c) ! { dg-error "" }
++ if (d_i .ne. 1) STOP 13
++ d_i = DIM(a2_i, b2_c) ! { dg-error "" }
++ if (d_i .ne. 1) STOP 14
++ d_r = DIM(a_r, b_l) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
++ d_r = DIM(a2_r, b2_l) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
++ d_r = DIM(a_r, b_c) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
++ d_r = DIM(b_c, a_r) ! { dg-error "" }
++ if (abs(d_r) > 1.0D-6) STOP 18
++
++ s_i = SIGN(-a_i, b_c) ! { dg-error "" }
++ if (s_i .ne. 4) STOP 19
++ s_i = SIGN(-a2_i, b2_c) ! { dg-error "" }
++ if (s_i .ne. 4) STOP 20
++ s_r = SIGN(a_r, -b_l) ! { dg-error "" }
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
++ s_r = SIGN(a2_r, -b2_l) ! { dg-error "" }
++ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
++ s_r = SIGN(a_r, -b_c) ! { dg-error "" }
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
++ s_r = SIGN(-a_i, b_l) ! { dg-error "" }
++ if (abs(s_r - a_r) > 1.0D-6) STOP 24
++
++ mx_i = MAX(-a_i, -b_c, x_i, y_c) ! { dg-error "" }
++ if (mx_i .ne. x_i) STOP 25
++ mx_i = MAX(-a2_i, -b2_c, x_i, y_c) ! { dg-error "" }
++ if (mx_i .ne. x_i) STOP 26
++ mx_r = MAX(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
++ mx_r = MAX(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
++ mx_r = MAX(-a_i, -b_l, x_r, y_c) ! { dg-error "" }
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
++
++ mn_i = MIN(-a_i, -b_c, x_i, y_c) ! { dg-error "" }
++ if (mn_i .ne. -a_i) STOP 31
++ mn_i = MIN(-a2_i, -b2_c, x_i, y_c) ! { dg-error "" }
++ if (mn_i .ne. -a2_i) STOP 32
++ mn_r = MIN(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
++ mn_r = MIN(-a2_r, -b2_l, x_r, y_l) ! { dg-error "" }
++ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
++ mn_r = MIN(-a_i, -b_l, x_r, y_c) ! { dg-error "" }
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
+new file mode 100644
+index 00000000000..1d4150d81c0
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
+@@ -0,0 +1,118 @@
++! { dg-do compile }
++! { dg-options "-fdec-promotion" }
++!
++! Test promotion between integers and reals in intrinsic operations.
++! These operations are: mod, modulo, dim, sign, min, max, minloc and
++! maxloc.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! and Jeff Law <law@redhat.com>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ PROGRAM promotion_int_real
++ REAL l/0.0/
++ INTEGER a_i/4/
++ INTEGER*4 a2_i/4/
++ CHARACTER b_c
++ CHARACTER*8 b2_c
++ INTEGER x_i/2/
++ CHARACTER y_c
++ REAL a_r/4.0/
++ REAL*4 a2_r/4.0/
++ LOGICAL b_l
++ LOGICAL*8 b2_l
++ REAL x_r/2.0/
++ LOGICAL y_l
++
++ INTEGER m_i/0/
++ REAL m_r/0.0/
++
++ INTEGER md_i/0/
++ REAL md_r/0.0/
++
++ INTEGER d_i/0/
++ REAL d_r/0.0/
++
++ INTEGER s_i/0/
++ REAL s_r/0.0/
++
++ INTEGER mn_i/0/
++ REAL mn_r/0.0/
++
++ INTEGER mx_i/0/
++ REAL mx_r/0.0/
++
++ m_i = MOD(a_i, b_c) ! { dg-error "" }
++ if (m_i .ne. 1) STOP 1
++ m_i = MOD(a2_i, b2_c) ! { dg-error "" }
++ if (m_i .ne. 1) STOP 2
++ m_r = MOD(a_r, b_l) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
++ m_r = MOD(a2_r, b2_l) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
++ m_r = MOD(a_i, b_l) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
++ m_r = MOD(a_r, b_c) ! { dg-error "" }
++ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
++
++ md_i = MODULO(a_i, b_c) ! { dg-error "" }
++ if (md_i .ne. 1) STOP 7
++ md_i = MODULO(a2_i, b2_c) ! { dg-error "" }
++ if (md_i .ne. 1) STOP 8
++ md_r = MODULO(a_r, b_l) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
++ md_r = MODULO(a2_r, b2_l) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
++ md_r = MODULO(a_i, b_l) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
++ md_r = MODULO(a_r, b_c) ! { dg-error "" }
++ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
++
++ d_i = DIM(a_i, b_c) ! { dg-error "" }
++ if (d_i .ne. 1) STOP 13
++ d_i = DIM(a2_i, b2_c) ! { dg-error "" }
++ if (d_i .ne. 1) STOP 14
++ d_r = DIM(a_r, b_l) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
++ d_r = DIM(a2_r, b2_l) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
++ d_r = DIM(a_r, b_c) ! { dg-error "" }
++ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
++ d_r = DIM(b_c, a_r) ! { dg-error "" }
++ if (abs(d_r) > 1.0D-6) STOP 18
++
++ s_i = SIGN(-a_i, b_c) ! { dg-error "" }
++ if (s_i .ne. 4) STOP 19
++ s_i = SIGN(-a2_i, b2_c) ! { dg-error "" }
++ if (s_i .ne. 4) STOP 20
++ s_r = SIGN(a_r, -b_l) ! { dg-error "" }
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
++ s_r = SIGN(a2_r, -b2_l) ! { dg-error "" }
++ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
++ s_r = SIGN(a_r, -b_c) ! { dg-error "" }
++ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
++ s_r = SIGN(-a_i, b_l) ! { dg-error "" }
++ if (abs(s_r - a_r) > 1.0D-6) STOP 24
++
++ mx_i = MAX(-a_i, -b_c, x_i, y_c) ! { dg-error "" }
++ if (mx_i .ne. x_i) STOP 25
++ mx_i = MAX(-a2_i, -b2_c, x_i, y_c) ! { dg-error "" }
++ if (mx_i .ne. x_i) STOP 26
++ mx_r = MAX(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
++ mx_r = MAX(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
++ mx_r = MAX(-a_i, -b_l, x_r, y_c) ! { dg-error "" }
++ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
++
++ mn_i = MIN(-a_i, -b_c, x_i, y_c) ! { dg-error "" }
++ if (mn_i .ne. -a_i) STOP 31
++ mn_i = MIN(-a2_i, -b2_c, x_i, y_c) ! { dg-error "" }
++ if (mn_i .ne. -a2_i) STOP 32
++ mn_r = MIN(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
++ mn_r = MIN(-a2_r, -b2_l, x_r, y_l) ! { dg-error "" }
++ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
++ mn_r = MIN(-a_i, -b_l, x_r, y_c) ! { dg-error "" }
++ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
++ END PROGRAM
+diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
+new file mode 100644
+index 00000000000..435bf98350c
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
+@@ -0,0 +1,40 @@
++!{ dg-do run }
++!{ dg-options "-fdec" }
++!
++! integer types of a smaller kind than expected should be
++! accepted by type specific intrinsic functions
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program test_small_type_promtion
++ implicit none
++ integer(1) :: a = 1
++ integer :: i
++ if (iiabs(-9_1).ne.9) stop 1
++ if (iabs(-9_1).ne.9) stop 2
++ if (iabs(-9_2).ne.9) stop 3
++ if (jiabs(-9_1).ne.9) stop 4
++ if (jiabs(-9_2).ne.9) stop 5
++ if (iishft(1_1, 2).ne.4) stop 6
++ if (jishft(1_1, 2).ne.4) stop 7
++ if (jishft(1_2, 2).ne.4) stop 8
++ if (kishft(1_1, 2).ne.4) stop 9
++ if (kishft(1_2, 2).ne.4) stop 10
++ if (kishft(1_4, 2).ne.4) stop 11
++ if (imod(17_1, 3).ne.2) stop 12
++ if (jmod(17_1, 3).ne.2) stop 13
++ if (jmod(17_2, 3).ne.2) stop 14
++ if (kmod(17_1, 3).ne.2) stop 15
++ if (kmod(17_2, 3).ne.2) stop 16
++ if (kmod(17_4, 3).ne.2) stop 17
++ if (inot(5_1).ne.-6) stop 18
++ if (jnot(5_1).ne.-6) stop 19
++ if (jnot(5_2).ne.-6) stop 20
++ if (knot(5_1).ne.-6) stop 21
++ if (knot(5_2).ne.-6) stop 22
++ if (knot(5_4).ne.-6) stop 23
++ if (isign(-77_1, 1).ne.77) stop 24
++ if (isign(-77_1, -1).ne.-77) stop 25
++ if (isign(-77_2, 1).ne.77) stop 26
++ if (isign(-77_2, -1).ne.-77) stop 27
++ end program
+diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
+new file mode 100644
+index 00000000000..7b1697ca665
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
+@@ -0,0 +1,40 @@
++!{ dg-do run }
++!{ dg-options "-fdec-intrinsic-ints -fdec-promotion" }
++!
++! integer types of a smaller kind than expected should be
++! accepted by type specific intrinsic functions
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program test_small_type_promtion
++ implicit none
++ integer(1) :: a = 1
++ integer :: i
++ if (iiabs(-9_1).ne.9) stop 1
++ if (iabs(-9_1).ne.9) stop 2
++ if (iabs(-9_2).ne.9) stop 3
++ if (jiabs(-9_1).ne.9) stop 4
++ if (jiabs(-9_2).ne.9) stop 5
++ if (iishft(1_1, 2).ne.4) stop 6
++ if (jishft(1_1, 2).ne.4) stop 7
++ if (jishft(1_2, 2).ne.4) stop 8
++ if (kishft(1_1, 2).ne.4) stop 9
++ if (kishft(1_2, 2).ne.4) stop 10
++ if (kishft(1_4, 2).ne.4) stop 11
++ if (imod(17_1, 3).ne.2) stop 12
++ if (jmod(17_1, 3).ne.2) stop 13
++ if (jmod(17_2, 3).ne.2) stop 14
++ if (kmod(17_1, 3).ne.2) stop 15
++ if (kmod(17_2, 3).ne.2) stop 16
++ if (kmod(17_4, 3).ne.2) stop 17
++ if (inot(5_1).ne.-6) stop 18
++ if (jnot(5_1).ne.-6) stop 19
++ if (jnot(5_2).ne.-6) stop 20
++ if (knot(5_1).ne.-6) stop 21
++ if (knot(5_2).ne.-6) stop 22
++ if (knot(5_4).ne.-6) stop 23
++ if (isign(-77_1, 1).ne.77) stop 24
++ if (isign(-77_1, -1).ne.-77) stop 25
++ if (isign(-77_2, 1).ne.77) stop 26
++ if (isign(-77_2, -1).ne.-77) stop 27
++ end program
+diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
+new file mode 100644
+index 00000000000..db8dff6c55d
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
+@@ -0,0 +1,39 @@
++!{ dg-do compile }
++!{ dg-options "-fdec -fno-dec-promotion" }
++!
++! integer types of a smaller kind than expected should be
++! accepted by type specific intrinsic functions
++!
++! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ program test_small_type_promtion
++ integer(1) :: a = 1
++ integer :: i
++ if (iiabs(-9_1).ne.9) stop 1
++ if (iabs(-9_1).ne.9) stop 2 ! { dg-error "type mismatch in argument" }
++ if (iabs(-9_2).ne.9) stop 3 ! { dg-error "type mismatch in argument" }
++ if (jiabs(-9_1).ne.9) stop 4
++ if (jiabs(-9_2).ne.9) stop 5
++ if (iishft(1_1, 2).ne.4) stop 6
++ if (jishft(1_1, 2).ne.4) stop 7
++ if (jishft(1_2, 2).ne.4) stop 8
++ if (kishft(1_1, 2).ne.4) stop 9
++ if (kishft(1_2, 2).ne.4) stop 10
++ if (kishft(1_4, 2).ne.4) stop 11
++ if (imod(17_1, 3).ne.2) stop 12
++ if (jmod(17_1, 3).ne.2) stop 13
++ if (jmod(17_2, 3).ne.2) stop 14
++ if (kmod(17_1, 3).ne.2) stop 15
++ if (kmod(17_2, 3).ne.2) stop 16
++ if (kmod(17_4, 3).ne.2) stop 17
++ if (inot(5_1).ne.-6) stop 18
++ if (jnot(5_1).ne.-6) stop 19
++ if (jnot(5_2).ne.-6) stop 20
++ if (knot(5_1).ne.-6) stop 21
++ if (knot(5_2).ne.-6) stop 22
++ if (knot(5_4).ne.-6) stop 23
++ if (isign(-77_1, 1).ne.77) stop 24 ! { dg-error "type mismatch in argument" }
++ if (isign(-77_1, -1).ne.-77) stop 25 ! { dg-error "type mismatch in argument" }
++ if (isign(-77_2, 1).ne.77) stop 26 ! { dg-error "type mismatch in argument" }
++ if (isign(-77_2, -1).ne.-77) stop 27 ! { dg-error "type mismatch in argument" }
++ end program
+--
+2.27.0
+
diff --git a/gcc11-fortran-fdec-sequence.patch b/gcc11-fortran-fdec-sequence.patch
new file mode 100644
index 0000000..cef8b09
--- /dev/null
+++ b/gcc11-fortran-fdec-sequence.patch
@@ -0,0 +1,262 @@
+From bb76446db10c21860a4e19569ce3e350d8a2b59f Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 15:00:44 +0000
+Subject: [PATCH 09/10] Add the SEQUENCE attribute by default if it's not
+ present.
+
+Use -fdec-sequence to enable this feature. Also enabled by -fdec.
+---
+ gcc/fortran/lang.opt | 4 ++
+ gcc/fortran/options.c | 1 +
+ gcc/fortran/resolve.c | 13 ++++-
+ ...dd_SEQUENCE_to_COMMON_block_by_default_1.f | 57 +++++++++++++++++++
+ ...dd_SEQUENCE_to_COMMON_block_by_default_2.f | 57 +++++++++++++++++++
+ ...dd_SEQUENCE_to_COMMON_block_by_default_3.f | 57 +++++++++++++++++++
+ 6 files changed, 186 insertions(+), 3 deletions(-)
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_3.f
+
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index 4ca2f93f2df..019c798cf09 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -509,6 +509,10 @@ fdec-promotion
+ Fortran Var(flag_dec_promotion)
+ Add support for type promotion in intrinsic arguments
+
++fdec-sequence
++Fortran Var(flag_dec_sequence)
++Add the SEQUENCE attribute by default if it's not present
++
+ fdec-structure
+ Fortran Var(flag_dec_structure)
+ Enable support for DEC STRUCTURE/RECORD.
+diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
+index 15079c7e95a..050f56fdc25 100644
+--- a/gcc/fortran/options.c
++++ b/gcc/fortran/options.c
+@@ -83,6 +83,7 @@ set_dec_flags (int value)
+ SET_BITFLAG (flag_dec_override_kind, value, value);
+ SET_BITFLAG (flag_dec_non_logical_if, value, value);
+ SET_BITFLAG (flag_dec_promotion, value, value);
++ SET_BITFLAG (flag_dec_sequence, value, value);
+ }
+
+ /* Finalize DEC flags. */
+diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
+index 07dd039f3bf..fe7d0cc5944 100644
+--- a/gcc/fortran/resolve.c
++++ b/gcc/fortran/resolve.c
+@@ -978,9 +978,16 @@ resolve_common_vars (gfc_common_head *common_block, bool named_common)
+
+ if (!(csym->ts.u.derived->attr.sequence
+ || csym->ts.u.derived->attr.is_bind_c))
+- gfc_error_now ("Derived type variable %qs in COMMON at %L "
+- "has neither the SEQUENCE nor the BIND(C) "
+- "attribute", csym->name, &csym->declared_at);
++ {
++ if (flag_dec_sequence)
++ /* Assume sequence. */
++ csym->ts.u.derived->attr.sequence = 1;
++ else
++ gfc_error_now ("Derived type variable '%s' in COMMON at %L "
++ "has neither the SEQUENCE nor the BIND(C) "
++ "attribute", csym->name, &csym->declared_at);
++ }
++
+ if (csym->ts.u.derived->attr.alloc_comp)
+ gfc_error_now ("Derived type variable %qs in COMMON at %L "
+ "has an ultimate component that is "
+diff --git a/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_1.f b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_1.f
+new file mode 100644
+index 00000000000..fe7b39625eb
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_1.f
+@@ -0,0 +1,57 @@
++! { dg-do run }
++! { dg-options "-fdec" }
++!
++! Test add default SEQUENCE attribute derived types appearing in
++! COMMON blocks and EQUIVALENCE statements.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ MODULE SEQ
++ TYPE STRUCT1
++ INTEGER*4 ID
++ INTEGER*4 TYPE
++ INTEGER*8 DEFVAL
++ CHARACTER*(4) NAME
++ LOGICAL*1 NIL
++ END TYPE STRUCT1
++ END MODULE
++
++ SUBROUTINE A
++ USE SEQ
++ TYPE (STRUCT1) S
++ COMMON /BLOCK1/ S
++ IF (S%ID.NE.5) STOP 1
++ IF (S%TYPE.NE.1000) STOP 2
++ IF (S%DEFVAL.NE.-99) STOP 3
++ IF (S%NAME.NE."JANE") STOP 4
++ IF (S%NIL.NEQV..FALSE.) STOP 5
++ END SUBROUTINE
++
++ PROGRAM sequence_att_common
++ USE SEQ
++ IMPLICIT NONE
++ TYPE (STRUCT1) S1
++ TYPE (STRUCT1) S2
++ TYPE (STRUCT1) S3
++
++ EQUIVALENCE (S1,S2)
++ COMMON /BLOCK1/ S3
++
++ S1%ID = 5
++ S1%TYPE = 1000
++ S1%DEFVAL = -99
++ S1%NAME = "JANE"
++ S1%NIL = .FALSE.
++
++ IF (S2%ID.NE.5) STOP 1
++ IF (S2%TYPE.NE.1000) STOP 2
++ IF (S2%DEFVAL.NE.-99) STOP 3
++ IF (S2%NAME.NE."JANE") STOP 4
++ IF (S2%NIL.NEQV..FALSE.) STOP 5
++
++ S3 = S1
++
++ CALL A
++
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_2.f b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_2.f
+new file mode 100644
+index 00000000000..83512f0f3a2
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_2.f
+@@ -0,0 +1,57 @@
++! { dg-do run }
++! { dg-options "-fdec-sequence" }
++!
++! Test add default SEQUENCE attribute derived types appearing in
++! COMMON blocks and EQUIVALENCE statements.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ MODULE SEQ
++ TYPE STRUCT1
++ INTEGER*4 ID
++ INTEGER*4 TYPE
++ INTEGER*8 DEFVAL
++ CHARACTER*(4) NAME
++ LOGICAL*1 NIL
++ END TYPE STRUCT1
++ END MODULE
++
++ SUBROUTINE A
++ USE SEQ
++ TYPE (STRUCT1) S
++ COMMON /BLOCK1/ S
++ IF (S%ID.NE.5) STOP 1
++ IF (S%TYPE.NE.1000) STOP 2
++ IF (S%DEFVAL.NE.-99) STOP 3
++ IF (S%NAME.NE."JANE") STOP 4
++ IF (S%NIL.NEQV..FALSE.) STOP 5
++ END SUBROUTINE
++
++ PROGRAM sequence_att_common
++ USE SEQ
++ IMPLICIT NONE
++ TYPE (STRUCT1) S1
++ TYPE (STRUCT1) S2
++ TYPE (STRUCT1) S3
++
++ EQUIVALENCE (S1,S2)
++ COMMON /BLOCK1/ S3
++
++ S1%ID = 5
++ S1%TYPE = 1000
++ S1%DEFVAL = -99
++ S1%NAME = "JANE"
++ S1%NIL = .FALSE.
++
++ IF (S2%ID.NE.5) STOP 1
++ IF (S2%TYPE.NE.1000) STOP 2
++ IF (S2%DEFVAL.NE.-99) STOP 3
++ IF (S2%NAME.NE."JANE") STOP 4
++ IF (S2%NIL.NEQV..FALSE.) STOP 5
++
++ S3 = S1
++
++ CALL A
++
++ END
+diff --git a/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_3.f b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_3.f
+new file mode 100644
+index 00000000000..26cd59f9090
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/dec_add_SEQUENCE_to_COMMON_block_by_default_3.f
+@@ -0,0 +1,57 @@
++! { dg-do compile }
++! { dg-options "-fdec -fno-dec-sequence" }
++!
++! Test add default SEQUENCE attribute derived types appearing in
++! COMMON blocks and EQUIVALENCE statements.
++!
++! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
++! Modified by Mark Eggleston <mark.eggleston@codethink.com>
++!
++ MODULE SEQ
++ TYPE STRUCT1
++ INTEGER*4 ID
++ INTEGER*4 TYPE
++ INTEGER*8 DEFVAL
++ CHARACTER*(4) NAME
++ LOGICAL*1 NIL
++ END TYPE STRUCT1
++ END MODULE
++
++ SUBROUTINE A
++ USE SEQ
++ TYPE (STRUCT1) S ! { dg-error "Derived type variable" }
++ COMMON /BLOCK1/ S
++ IF (S%ID.NE.5) STOP 1
++ IF (S%TYPE.NE.1000) STOP 2
++ IF (S%DEFVAL.NE.-99) STOP 3
++ IF (S%NAME.NE."JANE") STOP 4
++ IF (S%NIL.NEQV..FALSE.) STOP 5
++ END SUBROUTINE
++
++ PROGRAM sequence_att_common
++ USE SEQ
++ IMPLICIT NONE
++ TYPE (STRUCT1) S1
++ TYPE (STRUCT1) S2
++ TYPE (STRUCT1) S3 ! { dg-error "Derived type variable" }
++
++ EQUIVALENCE (S1,S2) ! { dg-error "Derived type variable" }
++ COMMON /BLOCK1/ S3
++
++ S1%ID = 5
++ S1%TYPE = 1000
++ S1%DEFVAL = -99
++ S1%NAME = "JANE"
++ S1%NIL = .FALSE.
++
++ IF (S2%ID.NE.5) STOP 1
++ IF (S2%TYPE.NE.1000) STOP 2
++ IF (S2%DEFVAL.NE.-99) STOP 3
++ IF (S2%NAME.NE."JANE") STOP 4
++ IF (S2%NIL.NEQV..FALSE.) STOP 5
++
++ S3 = S1
++
++ CALL A
++
++ END
+--
+2.27.0
+
diff --git a/gcc11-fortran-flogical-as-integer.patch b/gcc11-fortran-flogical-as-integer.patch
new file mode 100644
index 0000000..41cbf60
--- /dev/null
+++ b/gcc11-fortran-flogical-as-integer.patch
@@ -0,0 +1,305 @@
+From 9b45f3063dfd2b893e7963a4828c1b0afecdc68a Mon Sep 17 00:00:00 2001
+From: Mark Eggleston <markeggleston@gcc.gnu.org>
+Date: Fri, 22 Jan 2021 12:41:46 +0000
+Subject: [PATCH 02/10] Convert LOGICAL to INTEGER for arithmetic ops, and vice
+ versa
+
+We allow converting LOGICAL types to INTEGER when doing arithmetic
+operations, and converting INTEGER types to LOGICAL for use in
+boolean operations.
+
+This feature is enabled with the -flogical-as-integer flag.
+
+Note: using this feature will disable bitwise logical operations enabled by
+-fdec.
+---
+ gcc/fortran/lang.opt | 4 ++
+ gcc/fortran/resolve.c | 55 ++++++++++++++++++-
+ .../logical_to_integer_and_vice_versa_1.f | 31 +++++++++++
+ .../logical_to_integer_and_vice_versa_2.f | 31 +++++++++++
+ .../logical_to_integer_and_vice_versa_3.f | 33 +++++++++++
+ .../logical_to_integer_and_vice_versa_4.f | 33 +++++++++++
+ 6 files changed, 186 insertions(+), 1 deletion(-)
+ create mode 100644 gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_1.f
+ create mode 100644 gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_2.f
+ create mode 100644 gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_3.f
+ create mode 100644 gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_4.f
+
+diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
+index 52bd522051e..c4da248f07c 100644
+--- a/gcc/fortran/lang.opt
++++ b/gcc/fortran/lang.opt
+@@ -497,6 +497,10 @@ fdec-static
+ Fortran Var(flag_dec_static)
+ Enable DEC-style STATIC and AUTOMATIC attributes.
+
++flogical-as-integer
++Fortran Var(flag_logical_as_integer)
++Convert from integer to logical or logical to integer for arithmetic operations.
++
+ fdefault-double-8
+ Fortran Var(flag_default_double)
+ Set the default double precision kind to an 8 byte wide type.
+diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
+index c075d0fa0c4..4b90cb59902 100644
+--- a/gcc/fortran/resolve.c
++++ b/gcc/fortran/resolve.c
+@@ -3915,7 +3915,6 @@ lookup_uop_fuzzy (const char *op, gfc_symtree *uop)
+ return gfc_closest_fuzzy_match (op, candidates);
+ }
+
+-
+ /* Callback finding an impure function as an operand to an .and. or
+ .or. expression. Remember the last function warned about to
+ avoid double warnings when recursing. */
+@@ -3975,6 +3974,22 @@ convert_hollerith_to_character (gfc_expr *e)
+ }
+ }
+
++/* If E is a logical, convert it to an integer and issue a warning
++ for the conversion. */
++
++static void
++convert_integer_to_logical (gfc_expr *e)
++{
++ if (e->ts.type == BT_INTEGER)
++ {
++ /* Convert to LOGICAL */
++ gfc_typespec t;
++ t.type = BT_LOGICAL;
++ t.kind = 1;
++ gfc_convert_type_warn (e, &t, 2, 1);
++ }
++}
++
+ /* Convert to numeric and issue a warning for the conversion. */
+
+ static void
+@@ -3987,6 +4002,22 @@ convert_to_numeric (gfc_expr *a, gfc_expr *b)
+ gfc_convert_type_warn (a, &t, 2, 1);
+ }
+
++/* If E is a logical, convert it to an integer and issue a warning
++ for the conversion. */
++
++static void
++convert_logical_to_integer (gfc_expr *e)
++{
++ if (e->ts.type == BT_LOGICAL)
++ {
++ /* Convert to INTEGER */
++ gfc_typespec t;
++ t.type = BT_INTEGER;
++ t.kind = 1;
++ gfc_convert_type_warn (e, &t, 2, 1);
++ }
++}
++
+ /* Resolve an operator expression node. This can involve replacing the
+ operation with a user defined function call. */
+
+@@ -4072,6 +4103,12 @@ resolve_operator (gfc_expr *e)
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+ case INTRINSIC_POWER:
++ if (flag_logical_as_integer)
++ {
++ convert_logical_to_integer (op1);
++ convert_logical_to_integer (op2);
++ }
++
+ if (gfc_numeric_ts (&op1->ts) && gfc_numeric_ts (&op2->ts))
+ {
+ gfc_type_convert_binary (e, 1);
+@@ -4108,6 +4145,13 @@ resolve_operator (gfc_expr *e)
+ case INTRINSIC_OR:
+ case INTRINSIC_EQV:
+ case INTRINSIC_NEQV:
++
++ if (flag_logical_as_integer)
++ {
++ convert_integer_to_logical (op1);
++ convert_integer_to_logical (op2);
++ }
++
+ if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
+ {
+ e->ts.type = BT_LOGICAL;
+@@ -4158,6 +4202,9 @@ resolve_operator (gfc_expr *e)
+ goto simplify_op;
+ }
+
++ if (flag_logical_as_integer)
++ convert_integer_to_logical (op1);
++
+ if (op1->ts.type == BT_LOGICAL)
+ {
+ e->ts.type = BT_LOGICAL;
+@@ -4198,6 +4245,12 @@ resolve_operator (gfc_expr *e)
+ convert_hollerith_to_character (op2);
+ }
+
++ if (flag_logical_as_integer)
++ {
++ convert_logical_to_integer (op1);
++ convert_logical_to_integer (op2);
++ }
++
+ if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
+ && op1->ts.kind == op2->ts.kind)
+ {
+diff --git a/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_1.f b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_1.f
+new file mode 100644
+index 00000000000..938a91d9e9a
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_1.f
+@@ -0,0 +1,31 @@
++! { dg-do run }
++! { dg-options "-std=legacy -flogical-as-integer" }
++!
++! Test conversion between logical and integer for logical operators
++!
++! Test case contributed by Jim MacArthur <jim.macarthur@codethink.co.uk>
++! Modified for -flogical-as-integer by Mark Eggleston
++! <mark.eggleston@codethink.com>
++!
++ PROGRAM logical_integer_conversion
++ LOGICAL lpos /.true./
++ INTEGER ineg/0/
++ INTEGER ires
++ LOGICAL lres
++
++ ! Test Logicals converted to Integers
++ if ((lpos.AND.ineg).EQ.1) STOP 3
++ if ((ineg.AND.lpos).NE.0) STOP 4
++ ires = (.true..AND.0)
++ if (ires.NE.0) STOP 5
++ ires = (1.AND..false.)
++ if (ires.EQ.1) STOP 6
++
++ ! Test Integers converted to Logicals
++ if (lpos.EQ.ineg) STOP 7
++ if (ineg.EQ.lpos) STOP 8
++ lres = (.true..EQ.0)
++ if (lres) STOP 9
++ lres = (1.EQ..false.)
++ if (lres) STOP 10
++ END
+diff --git a/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_2.f b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_2.f
+new file mode 100644
+index 00000000000..9f146202ba5
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_2.f
+@@ -0,0 +1,31 @@
++! { dg-do compile }
++! { dg-options "-std=legacy -flogical-as-integer -fno-logical-as-integer" }
++!
++! Based on logical_to_integer_and_vice_versa_1.f but with option disabled
++! to test for error messages.
++!
++! Test case contributed by by Mark Eggleston <mark.eggleston@codethink.com>
++!
++!
++ PROGRAM logical_integer_conversion
++ LOGICAL lpos /.true./
++ INTEGER ineg/0/
++ INTEGER ires
++ LOGICAL lres
++
++ ! Test Logicals converted to Integers
++ if ((lpos.AND.ineg).EQ.1) STOP 3 ! { dg-error "Operands of logical operator" }
++ if ((ineg.AND.lpos).NE.0) STOP 4 ! { dg-error "Operands of logical operator" }
++ ires = (.true..AND.0) ! { dg-error "Operands of logical operator" }
++ if (ires.NE.0) STOP 5
++ ires = (1.AND..false.) ! { dg-error "Operands of logical operator" }
++ if (ires.EQ.1) STOP 6
++
++ ! Test Integers converted to Logicals
++ if (lpos.EQ.ineg) STOP 7 ! { dg-error "Operands of comparison operator" }
++ if (ineg.EQ.lpos) STOP 8 ! { dg-error "Operands of comparison operator" }
++ lres = (.true..EQ.0) ! { dg-error "Operands of comparison operator" }
++ if (lres) STOP 9
++ lres = (1.EQ..false.) ! { dg-error "Operands of comparison operator" }
++ if (lres) STOP 10
++ END
+diff --git a/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_3.f b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_3.f
+new file mode 100644
+index 00000000000..446873eb2dc
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_3.f
+@@ -0,0 +1,33 @@
++! { dg-do compile }
++! { dg-options "-std=legacy -flogical-as-integer" }
++!
++! Test conversion between logical and integer for logical operators
++!
++ program test
++ logical f /.false./
++ logical t /.true./
++ real x
++
++ x = 7.7
++ x = x + t*3.0
++ if (abs(x - 10.7).gt.0.00001) stop 1
++ x = x + .false.*5.0
++ if (abs(x - 10.7).gt.0.00001) stop 2
++ x = x - .true.*5.0
++ if (abs(x - 5.7).gt.0.00001) stop 3
++ x = x + t
++ if (abs(x - 6.7).gt.0.00001) stop 4
++ x = x + f
++ if (abs(x - 6.7).gt.0.00001) stop 5
++ x = x - t
++ if (abs(x - 5.7).gt.0.00001) stop 6
++ x = x - f
++ if (abs(x - 5.7).gt.0.00001) stop 7
++ x = x**.true.
++ if (abs(x - 5.7).gt.0.00001) stop 8
++ x = x**.false.
++ if (abs(x - 1.0).gt.0.00001) stop 9
++ x = x/t
++ if (abs(x - 1.0).gt.0.00001) stop 10
++ if ((x/.false.).le.huge(x)) stop 11
++ end
+diff --git a/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_4.f b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_4.f
+new file mode 100644
+index 00000000000..4301a4988d8
+--- /dev/null
++++ b/gcc/testsuite/gfortran.dg/logical_to_integer_and_vice_versa_4.f
+@@ -0,0 +1,33 @@
++! { dg-do compile }
++! { dg-options "-std=legacy -flogical-as-integer -fno-logical-as-integer" }
++!
++! Test conversion between logical and integer for logical operators
++!
++ program test
++ logical f /.false./
++ logical t /.true./
++ real x
++
++ x = 7.7
++ x = x + t*3.0 ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 10.7).gt.0.00001) stop 1
++ x = x + .false.*5.0 ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 10.7).gt.0.00001) stop 2
++ x = x - .true.*5.0 ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 5.7).gt.0.00001) stop 3
++ x = x + t ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 6.7).gt.0.00001) stop 4
++ x = x + f ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 6.7).gt.0.00001) stop 5
++ x = x - t ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 5.7).gt.0.00001) stop 6
++ x = x - f ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 5.7).gt.0.00001) stop 7
++ x = x**.true. ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 5.7).gt.0.00001) stop 8
++ x = x**.false. ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 1.0).gt.0.00001) stop 9
++ x = x/t ! { dg-error "Operands of binary numeric" }
++ if (abs(x - 1.0).gt.0.00001) stop 10
++ if ((x/.false.).le.huge(x)) stop 11 ! { dg-error "Operands of binary numeric" }
++ end
+--
+2.27.0
+
reply other threads:[~2026-06-29 12:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178273614778.1.8220343257517380169.rpms-gcc-c7b83880f7d3@fedoraproject.org \
--to=jakub@redhat.com \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox