diff --git a/gcc-12.0.1-20220214.tar.xz b/gcc-12.0.1-20220214.tar.xz
new file mode 100644
index 0000000000000000000000000000000000000000..622feb5eeeea6cb33f17d5e114eb617e6e88f41a
Binary files /dev/null and b/gcc-12.0.1-20220214.tar.xz differ
diff --git a/gcc.spec b/gcc.spec
new file mode 100644
index 0000000000000000000000000000000000000000..f88dab533715a66253b162df706b647eb049dc3d
--- /dev/null
+++ b/gcc.spec
@@ -0,0 +1,2335 @@
+%define anolis_release 1
+
+%global DATE 20220214
+%global gitrev 7222fb983d798306a83666324a92fce5e5881eb7
+%global gcc_version 12.0.1
+%global gcc_major 12
+# Note, gcc_release must be integer, if you want to add suffixes to
+# %%{release}, append them after %%{gcc_release} on Release: line.
+%global gcc_release 0
+%global nvptx_tools_gitrev 5f6f343a302d620b0868edab376c00b15741e39e
+%global newlib_cygwin_gitrev 50e2a63b04bdd018484605fbb954fd1bd5147fa0
+%global _unpackaged_files_terminate_build 0
+%global _performance_build 1
+# Hardening slows the compiler way too much.
+%undefine _hardened_build
+%undefine _auto_set_build_flags
+%undefine _annotated_build
+# Strip will fail on nvptx-none *.a archives and the brp-* scripts will
+# fail randomly depending on what is stripped last.
+%if 0%{?__brp_strip_static_archive:1}
+%global __brp_strip_static_archive %{__brp_strip_static_archive} || :
+%endif
+%if 0%{?__brp_strip_lto:1}
+%global __brp_strip_lto %{__brp_strip_lto} || :
+%endif
+%global build_ada 0
+%global build_objc 0
+%global build_go 0
+%global build_d 0
+
+%ifarch x86_64
+%global build_libquadmath 1
+%else
+%global build_libquadmath 0
+%endif
+%global build_libasan 1
+%global build_libtsan 1
+%global build_liblsan 1
+%global build_libubsan 1
+%global build_libatomic 1
+%global build_libitm 1
+%global build_isl 1
+%global build_libstdcxx_docs 1
+%global attr_ifunc 1
+%ifarch x86_64
+%global build_offload_nvptx 1
+%else
+%global build_offload_nvptx 0
+%endif
+%ifarch x86_64
+%global multilib_32_arch i686
+%endif
+Summary: Various compilers (C, C++, Objective-C, ...)
+Name: gcc
+Version: %{gcc_version}
+Release: %{gcc_release}.8.%{anolis_release}%{?dist}
+# libgcc, libgfortran, libgomp, libstdc++ and crtstuff have
+# GCC Runtime Exception.
+License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD
+# The source for this package was pulled from upstream's vcs.
+# %%{gitrev} is some commit from the
+# https://gcc.gnu.org/git/?p=gcc.git;h=refs/vendors/redhat/heads/gcc-%%{gcc_major}-branch
+# branch. Use the following commands to generate the tarball:
+# git clone --depth 1 git://gcc.gnu.org/git/gcc.git gcc-dir.tmp
+# git --git-dir=gcc-dir.tmp/.git fetch --depth 1 origin %%{gitrev}
+# git --git-dir=gcc-dir.tmp/.git archive --prefix=%%{name}-%%{version}-%%{DATE}/ %%{gitrev} | xz -9e > %%{name}-%%{version}-%%{DATE}.tar.xz
+# rm -rf gcc-dir.tmp
+Source0: gcc-%{version}-%{DATE}.tar.xz
+# The source for nvptx-tools package was pulled from upstream's vcs. Use the
+# following commands to generate the tarball:
+# git clone --depth 1 git://github.com/MentorEmbedded/nvptx-tools.git nvptx-tools-dir.tmp
+# git --git-dir=nvptx-tools-dir.tmp/.git fetch --depth 1 origin %%{nvptx_tools_gitrev}
+# git --git-dir=nvptx-tools-dir.tmp/.git archive --prefix=nvptx-tools-%%{nvptx_tools_gitrev}/ %%{nvptx_tools_gitrev} | xz -9e > nvptx-tools-%%{nvptx_tools_gitrev}.tar.xz
+# rm -rf nvptx-tools-dir.tmp
+Source1: nvptx-tools-%{nvptx_tools_gitrev}.tar.xz
+# The source for nvptx-newlib package was pulled from upstream's vcs. Use the
+# following commands to generate the tarball:
+# git clone git://sourceware.org/git/newlib-cygwin.git newlib-cygwin-dir.tmp
+# git --git-dir=newlib-cygwin-dir.tmp/.git archive --prefix=newlib-cygwin-%%{newlib_cygwin_gitrev}/ %%{newlib_cygwin_gitrev} ":(exclude)newlib/libc/sys/linux/include/rpc/*.[hx]" | xz -9e > newlib-cygwin-%%{newlib_cygwin_gitrev}.tar.xz
+# rm -rf newlib-cygwin-dir.tmp
+Source2: newlib-cygwin-%{newlib_cygwin_gitrev}.tar.xz
+%global isl_version 0.18
+Source3: https://gcc.gnu.org/pub/gcc/infrastructure/isl-%{isl_version}.tar.bz2
+URL: http://gcc.gnu.org
+BuildRequires: binutils >= 2.31
+# While gcc doesn't include statically linked binaries, during testing
+# -static is used several times.
+BuildRequires: glibc-static
+BuildRequires: zlib-devel, gettext, dejagnu, bison, flex, sharutils
+BuildRequires: texinfo, texinfo-tex, /usr/bin/pod2man
+BuildRequires: systemtap-sdt-devel >= 1.3
+BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 3.1.0, libmpc-devel >= 0.8.1
+BuildRequires: python3-devel, /usr/bin/python
+BuildRequires: gcc, gcc-c++, make
+%if %{build_go}
+BuildRequires: hostname, procps
+%endif
+# For VTA guality testing
+BuildRequires: gdb
+# Make sure pthread.h doesn't contain __thread tokens
+# Make sure glibc supports stack protector
+# Make sure glibc supports DT_GNU_HASH
+BuildRequires: glibc-devel >= 2.4.90-13
+BuildRequires: elfutils-devel >= 0.147
+BuildRequires: elfutils-libelf-devel >= 0.147
+BuildRequires: libzstd-devel
+%ifarch %{multilib_64_archs}
+# Ensure glibc{,-devel} is installed for both multilib arches
+BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so
+%endif
+%if %{build_ada}
+# Ada requires Ada to build
+BuildRequires: gcc-gnat >= 3.1, libgnat >= 3.1
+%endif
+%if %{build_d}
+# D requires D to build
+BuildRequires: gcc-gdc >= 11.0.0, libgphobos-static >= 11.0.0
+%endif
+%if %{build_libstdcxx_docs}
+BuildRequires: doxygen >= 1.7.1
+BuildRequires: graphviz, dblatex, texlive-collection-latex, docbook5-style-xsl
+%endif
+Requires: cpp = %{version}-%{release}
+Requires: binutils >= 2.31
+# Make sure gdb will understand DW_FORM_strp
+Conflicts: gdb < 5.1-2
+Requires: glibc-devel >= 2.2.90-12
+Requires: libgcc >= %{version}-%{release}
+Requires: libgomp = %{version}-%{release}
+# lto-wrapper invokes make
+Requires: make
+%if !%{build_ada}
+Obsoletes: gcc-gnat < %{version}-%{release}
+%endif
+Obsoletes: gcc-java < %{version}-%{release}
+AutoReq: true
+Provides: bundled(libiberty)
+Provides: bundled(libbacktrace)
+Provides: bundled(libffi)
+Provides: gcc(major) = %{gcc_major}
+
+Patch0: gcc12-hack.patch
+Patch2: gcc12-sparc-config-detection.patch
+Patch3: gcc12-libgomp-omp_h-multilib.patch
+Patch4: gcc12-libtool-no-rpath.patch
+Patch5: gcc12-isl-dl.patch
+Patch6: gcc12-isl-dl2.patch
+Patch7: gcc12-libstdc++-docs.patch
+Patch8: gcc12-no-add-needed.patch
+Patch9: gcc12-Wno-format-security.patch
+Patch10: gcc12-rh1574936.patch
+Patch11: gcc12-d-shared-libphobos.patch
+Patch12: gcc12-ifcvt-revert.patch
+Patch13: gcc12-pr104253.patch
+
+Patch100: gcc12-fortran-fdec-duplicates.patch
+Patch101: gcc12-fortran-flogical-as-integer.patch
+Patch102: gcc12-fortran-fdec-ichar.patch
+Patch103: gcc12-fortran-fdec-non-integer-index.patch
+Patch104: gcc12-fortran-fdec-old-init.patch
+Patch105: gcc12-fortran-fdec-override-kind.patch
+Patch106: gcc12-fortran-fdec-non-logical-if.patch
+Patch107: gcc12-fortran-fdec-promotion.patch
+Patch108: gcc12-fortran-fdec-sequence.patch
+Patch109: gcc12-fortran-fdec-add-missing-indexes.patch
+
+%global _gnu %{nil}
+
+%global gcc_target_platform %{_target_platform}
+
+%if %{build_go}
+# Avoid stripping these libraries and binaries.
+%global __os_install_post \
+chmod 644 %{buildroot}%{_prefix}/%{_lib}/libgo.so.21.* \
+chmod 644 %{buildroot}%{_prefix}/bin/go.gcc \
+chmod 644 %{buildroot}%{_prefix}/bin/gofmt.gcc \
+chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo \
+chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/buildid \
+chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json \
+chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet \
+%__os_install_post \
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgo.so.21.* \
+chmod 755 %{buildroot}%{_prefix}/bin/go.gcc \
+chmod 755 %{buildroot}%{_prefix}/bin/gofmt.gcc \
+chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo \
+chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/buildid \
+chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json \
+chmod 755 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet \
+%{nil}
+%endif
+
+%description
+The gcc package contains the GNU Compiler Collection version 12.
+You'll need this package in order to compile C code.
+
+%package -n libgcc
+Summary: GCC version 12 shared support library
+Autoreq: false
+%if !%{build_ada}
+Obsoletes: libgnat < %{version}-%{release}
+%endif
+Obsoletes: libmudflap
+Obsoletes: libmudflap-devel
+Obsoletes: libmudflap-static
+Obsoletes: libgcj < %{version}-%{release}
+Obsoletes: libgcj-devel < %{version}-%{release}
+Obsoletes: libgcj-src < %{version}-%{release}
+%ifarch x86_64
+Obsoletes: libcilkrts
+Obsoletes: libcilkrts-static
+Obsoletes: libmpx
+Obsoletes: libmpx-static
+%endif
+
+%description -n libgcc
+This package contains GCC shared support library which is needed
+e.g. for exception handling support.
+
+%package c++
+Summary: C++ support for GCC
+Requires: gcc = %{version}-%{release}
+Requires: libstdc++ = %{version}-%{release}
+Requires: libstdc++-devel = %{version}-%{release}
+Provides: gcc-g++ = %{version}-%{release}
+Provides: g++ = %{version}-%{release}
+Autoreq: true
+
+%description c++
+This package adds C++ support to the GNU Compiler Collection.
+It includes support for most of the current C++ specification,
+including templates and exception handling.
+
+%package -n libstdc++
+Summary: GNU Standard C++ Library
+Autoreq: true
+Requires: glibc >= 2.10.90-7
+
+%description -n libstdc++
+The libstdc++ package contains a rewritten standard compliant GCC Standard
+C++ Library.
+
+%package -n libstdc++-devel
+Summary: Header files and libraries for C++ development
+Requires: libstdc++%{?_isa} = %{version}-%{release}
+Autoreq: true
+
+%description -n libstdc++-devel
+This is the GNU implementation of the standard C++ libraries. This
+package includes the header files and libraries needed for C++
+development. This includes rewritten implementation of STL.
+
+%package -n libstdc++-static
+Summary: Static libraries for the GNU standard C++ library
+Requires: libstdc++-devel = %{version}-%{release}
+Autoreq: true
+
+%description -n libstdc++-static
+Static libraries for the GNU standard C++ library.
+
+%package -n libstdc++-docs
+Summary: Documentation for the GNU standard C++ library
+Autoreq: true
+
+%description -n libstdc++-docs
+Manual, doxygen generated API information and Frequently Asked Questions
+for the GNU standard C++ library.
+
+%package objc
+Summary: Objective-C support for GCC
+Requires: gcc = %{version}-%{release}
+Requires: libobjc = %{version}-%{release}
+Autoreq: true
+
+%description objc
+gcc-objc provides Objective-C support for the GCC.
+Mainly used on systems running NeXTSTEP, Objective-C is an
+object-oriented derivative of the C language.
+
+%package objc++
+Summary: Objective-C++ support for GCC
+Requires: gcc-c++ = %{version}-%{release}, gcc-objc = %{version}-%{release}
+Autoreq: true
+
+%description objc++
+gcc-objc++ package provides Objective-C++ support for the GCC.
+
+%package -n libobjc
+Summary: Objective-C runtime
+Autoreq: true
+
+%description -n libobjc
+This package contains Objective-C shared library which is needed to run
+Objective-C dynamically linked programs.
+
+%package gfortran
+Summary: Fortran support
+Requires: gcc = %{version}-%{release}
+Requires: libgfortran = %{version}-%{release}
+%if %{build_libquadmath}
+Requires: libquadmath = %{version}-%{release}
+Requires: libquadmath-devel = %{version}-%{release}
+%endif
+Provides: gcc-fortran = %{version}-%{release}
+Provides: gfortran = %{version}-%{release}
+Autoreq: true
+
+%description gfortran
+The gcc-gfortran package provides support for compiling Fortran
+programs with the GNU Compiler Collection.
+
+%package -n libgfortran
+Summary: Fortran runtime
+Autoreq: true
+%if %{build_libquadmath}
+Requires: libquadmath = %{version}-%{release}
+%endif
+
+%description -n libgfortran
+This package contains Fortran shared library which is needed to run
+Fortran dynamically linked programs.
+
+%package -n libgfortran-static
+Summary: Static Fortran libraries
+Requires: libgfortran = %{version}-%{release}
+Requires: gcc = %{version}-%{release}
+%if %{build_libquadmath}
+Requires: libquadmath-static = %{version}-%{release}
+%endif
+
+%description -n libgfortran-static
+This package contains static Fortran libraries.
+
+%package gdc
+Summary: D support
+Requires: gcc = %{version}-%{release}
+Requires: libgphobos = %{version}-%{release}
+Provides: gcc-d = %{version}-%{release}
+Provides: gdc = %{version}-%{release}
+Autoreq: true
+
+%description gdc
+The gcc-gdc package provides support for compiling D
+programs with the GNU Compiler Collection.
+
+%package -n libgphobos
+Summary: D runtime
+Autoreq: true
+
+%description -n libgphobos
+This package contains D shared library which is needed to run
+D dynamically linked programs.
+
+%package -n libgphobos-static
+Summary: Static D libraries
+Requires: libgphobos = %{version}-%{release}
+Requires: gcc-gdc = %{version}-%{release}
+
+%description -n libgphobos-static
+This package contains static D libraries.
+
+%package -n libgomp
+Summary: GCC OpenMP v4.5 shared support library
+
+%description -n libgomp
+This package contains GCC shared support library which is needed
+for OpenMP v4.5 support.
+
+%package -n libgomp-offload-nvptx
+Summary: GCC OpenMP v4.5 plugin for offloading to NVPTX
+Requires: libgomp = %{version}-%{release}
+
+%description -n libgomp-offload-nvptx
+This package contains libgomp plugin for offloading to NVidia
+PTX. The plugin needs libcuda.so.1 shared library that has to be
+installed separately.
+
+%package gdb-plugin
+Summary: GCC plugin for GDB
+Requires: gcc = %{version}-%{release}
+
+%description gdb-plugin
+This package contains GCC plugin for GDB C expression evaluation.
+
+%package -n libgccjit
+Summary: Library for embedding GCC inside programs and libraries
+Requires: gcc = %{version}-%{release}
+
+%description -n libgccjit
+This package contains shared library with GCC JIT front-end.
+
+%package -n libgccjit-devel
+Summary: Support for embedding GCC inside programs and libraries
+BuildRequires: python3-sphinx
+Requires: libgccjit = %{version}-%{release}
+
+%description -n libgccjit-devel
+This package contains header files and documentation for GCC JIT front-end.
+
+%package -n libquadmath
+Summary: GCC __float128 shared support library
+
+%description -n libquadmath
+This package contains GCC shared support library which is needed
+for __float128 math support and for Fortran REAL*16 support.
+
+%package -n libquadmath-devel
+Summary: GCC __float128 support
+Requires: libquadmath = %{version}-%{release}
+Requires: gcc = %{version}-%{release}
+
+%description -n libquadmath-devel
+This package contains headers for building Fortran programs using
+REAL*16 and programs using __float128 math.
+
+%package -n libquadmath-static
+Summary: Static libraries for __float128 support
+Requires: libquadmath-devel = %{version}-%{release}
+
+%description -n libquadmath-static
+This package contains static libraries for building Fortran programs
+using REAL*16 and programs using __float128 math.
+
+%package -n libitm
+Summary: The GNU Transactional Memory library
+
+%description -n libitm
+This package contains the GNU Transactional Memory library
+which is a GCC transactional memory support runtime library.
+
+%package -n libitm-devel
+Summary: The GNU Transactional Memory support
+Requires: libitm = %{version}-%{release}
+Requires: gcc = %{version}-%{release}
+
+%description -n libitm-devel
+This package contains headers and support files for the
+GNU Transactional Memory library.
+
+%package -n libitm-static
+Summary: The GNU Transactional Memory static library
+Requires: libitm-devel = %{version}-%{release}
+
+%description -n libitm-static
+This package contains GNU Transactional Memory static libraries.
+
+%package -n libatomic
+Summary: The GNU Atomic library
+
+%description -n libatomic
+This package contains the GNU Atomic library
+which is a GCC support runtime library for atomic operations not supported
+by hardware.
+
+%package -n libatomic-static
+Summary: The GNU Atomic static library
+Requires: libatomic = %{version}-%{release}
+
+%description -n libatomic-static
+This package contains GNU Atomic static libraries.
+
+%package -n libasan
+Summary: The Address Sanitizer runtime library
+
+%description -n libasan
+This package contains the Address Sanitizer library
+which is used for -fsanitize=address instrumented programs.
+
+%package -n libasan-static
+Summary: The Address Sanitizer static library
+Requires: libasan = %{version}-%{release}
+
+%description -n libasan-static
+This package contains Address Sanitizer static runtime library.
+
+%package -n libtsan
+Summary: The Thread Sanitizer runtime library
+
+%description -n libtsan
+This package contains the Thread Sanitizer library
+which is used for -fsanitize=thread instrumented programs.
+
+%package -n libtsan-static
+Summary: The Thread Sanitizer static library
+Requires: libtsan = %{version}-%{release}
+
+%description -n libtsan-static
+This package contains Thread Sanitizer static runtime library.
+
+%package -n libubsan
+Summary: The Undefined Behavior Sanitizer runtime library
+
+%description -n libubsan
+This package contains the Undefined Behavior Sanitizer library
+which is used for -fsanitize=undefined instrumented programs.
+
+%package -n libubsan-static
+Summary: The Undefined Behavior Sanitizer static library
+Requires: libubsan = %{version}-%{release}
+
+%description -n libubsan-static
+This package contains Undefined Behavior Sanitizer static runtime library.
+
+%package -n liblsan
+Summary: The Leak Sanitizer runtime library
+
+%description -n liblsan
+This package contains the Leak Sanitizer library
+which is used for -fsanitize=leak instrumented programs.
+
+%package -n liblsan-static
+Summary: The Leak Sanitizer static library
+Requires: liblsan = %{version}-%{release}
+
+%description -n liblsan-static
+This package contains Leak Sanitizer static runtime library.
+
+%package -n cpp
+Summary: The C Preprocessor
+Requires: filesystem >= 3
+Provides: /lib/cpp
+Autoreq: true
+
+%description -n cpp
+Cpp is the GNU C-Compatible Compiler Preprocessor.
+Cpp is a macro processor which is used automatically
+by the C compiler to transform your program before actual
+compilation. It is called a macro processor because it allows
+you to define macros, abbreviations for longer
+constructs.
+
+The C preprocessor provides four separate functionalities: the
+inclusion of header files (files of declarations that can be
+substituted into your program); macro expansion (you can define macros,
+and the C preprocessor will replace the macros with their definitions
+throughout the program); conditional compilation (using special
+preprocessing directives, you can include or exclude parts of the
+program according to various conditions); and line control (if you use
+a program to combine or rearrange source files into an intermediate
+file which is then compiled, you can use line control to inform the
+compiler about where each source line originated).
+
+You should install this package if you are a C programmer and you use
+macros.
+
+%package gnat
+Summary: Ada 83, 95, 2005 and 2012 support for GCC
+Requires: gcc = %{version}-%{release}
+Requires: libgnat = %{version}-%{release}, libgnat-devel = %{version}-%{release}
+Autoreq: true
+
+%description gnat
+GNAT is a GNU Ada 83, 95, 2005 and 2012 front-end to GCC. This package includes
+development tools, the documents and Ada compiler.
+
+%package -n libgnat
+Summary: GNU Ada 83, 95, 2005 and 2012 runtime shared libraries
+Autoreq: true
+
+%description -n libgnat
+GNAT is a GNU Ada 83, 95, 2005 and 2012 front-end to GCC. This package includes
+shared libraries, which are required to run programs compiled with the GNAT.
+
+%package -n libgnat-devel
+Summary: GNU Ada 83, 95, 2005 and 2012 libraries
+Autoreq: true
+
+%description -n libgnat-devel
+GNAT is a GNU Ada 83, 95, 2005 and 2012 front-end to GCC. This package includes
+libraries, which are required to compile with the GNAT.
+
+%package -n libgnat-static
+Summary: GNU Ada 83, 95, 2005 and 2012 static libraries
+Requires: libgnat-devel = %{version}-%{release}
+Autoreq: true
+
+%description -n libgnat-static
+GNAT is a GNU Ada 83, 95, 2005 and 2012 front-end to GCC. This package includes
+static libraries.
+
+%package go
+Summary: Go support
+Requires: gcc = %{version}-%{release}
+Requires: libgo = %{version}-%{release}
+Requires: libgo-devel = %{version}-%{release}
+Requires(post): %{_sbindir}/update-alternatives
+Requires(postun): %{_sbindir}/update-alternatives
+Provides: gccgo = %{version}-%{release}
+Autoreq: true
+
+%description go
+The gcc-go package provides support for compiling Go programs
+with the GNU Compiler Collection.
+
+%package -n libgo
+Summary: Go runtime
+Autoreq: true
+
+%description -n libgo
+This package contains Go shared library which is needed to run
+Go dynamically linked programs.
+
+%package -n libgo-devel
+Summary: Go development libraries
+Requires: libgo = %{version}-%{release}
+Autoreq: true
+
+%description -n libgo-devel
+This package includes libraries and support files for compiling
+Go programs.
+
+%package -n libgo-static
+Summary: Static Go libraries
+Requires: libgo = %{version}-%{release}
+Requires: gcc = %{version}-%{release}
+
+%description -n libgo-static
+This package contains static Go libraries.
+
+%package plugin-devel
+Summary: Support for compiling GCC plugins
+Requires: gcc = %{version}-%{release}
+Requires: gmp-devel >= 4.1.2-8, mpfr-devel >= 3.1.0, libmpc-devel >= 0.8.1
+
+%description plugin-devel
+This package contains header files and other support files
+for compiling GCC plugins. The GCC plugin ABI is currently
+not stable, so plugins must be rebuilt any time GCC is updated.
+
+%package offload-nvptx
+Summary: Offloading compiler to NVPTX
+Requires: gcc = %{version}-%{release}
+Requires: libgomp-offload-nvptx = %{version}-%{release}
+
+%description offload-nvptx
+The gcc-offload-nvptx package provides offloading support for
+NVidia PTX. OpenMP and OpenACC programs linked with -fopenmp will
+by default add PTX code into the binaries, which can be offloaded
+to NVidia PTX capable devices if available.
+
+%prep
+%setup -q -n gcc-%{version}-%{DATE} -a 1 -a 2 -a 3
+%patch0 -p0 -b .hack~
+%patch2 -p0 -b .sparc-config-detection~
+%patch3 -p0 -b .libgomp-omp_h-multilib~
+%patch4 -p0 -b .libtool-no-rpath~
+%if %{build_isl}
+%patch5 -p0 -b .isl-dl~
+%patch6 -p0 -b .isl-dl2~
+%endif
+%if %{build_libstdcxx_docs}
+%patch7 -p0 -b .libstdc++-docs~
+%endif
+%patch8 -p0 -b .no-add-needed~
+%patch9 -p0 -b .Wno-format-security~
+%patch10 -p0 -b .rh1574936~
+%patch11 -p0 -b .d-shared-libphobos~
+%patch12 -p0 -b .ifcvt-revert~
+%patch13 -p0 -b .pr104253~
+
+%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~
+
+rm -f libphobos/testsuite/libphobos.gc/forkgc2.d
+#rm -rf libphobos/testsuite/libphobos.gc
+
+echo 'Anolis OS %{version}-%{gcc_release}' > gcc/DEV-PHASE
+
+cp -a libstdc++-v3/config/cpu/i{4,3}86/atomicity.h
+
+./contrib/gcc_update --touch
+
+LC_ALL=C sed -i -e 's/\xa0/ /' gcc/doc/options.texi
+
+sed -i -e 's/Common Driver Var(flag_report_bug)/& Init(1)/' gcc/common.opt
+
+# This test causes fork failures, because it spawns way too many threads
+rm -f gcc/testsuite/go.test/test/chan/goroutines.go
+
+%build
+
+# Undo the broken autoconf change in recent Fedora versions
+export CONFIG_SITE=NONE
+
+CC=gcc
+CXX=g++
+OPT_FLAGS=`echo %{optflags}|sed -e 's/\(-Wp,\)\?-D_FORTIFY_SOURCE=[12]//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-flto=auto//g;s/-flto//g;s/-ffat-lto-objects//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-m64//g;s/-m32//g;s/-m31//g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mfpmath=sse/-mfpmath=sse -msse2/g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/ -pipe / /g'`
+OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-Werror=format-security/-Wformat-security/g'`
+OPT_FLAGS=`echo "$OPT_FLAGS" | sed -e 's/[[:blank:]]\+/ /g'`
+case "$OPT_FLAGS" in
+ *-fasynchronous-unwind-tables*)
+ sed -i -e 's/-fno-exceptions /-fno-exceptions -fno-asynchronous-unwind-tables /' \
+ libgcc/Makefile.in
+ ;;
+esac
+
+%if %{build_offload_nvptx}
+mkdir obji
+IROOT=`pwd`/obji
+cd nvptx-tools-%{nvptx_tools_gitrev}
+rm -rf obj-%{gcc_target_platform}
+mkdir obj-%{gcc_target_platform}
+cd obj-%{gcc_target_platform}
+CC="$CC" CXX="$CXX" CFLAGS="%{optflags}" CXXFLAGS="%{optflags}" \
+../configure --prefix=%{_prefix}
+make %{?_smp_mflags}
+make install prefix=${IROOT}%{_prefix}
+cd ../..
+
+ln -sf newlib-cygwin-%{newlib_cygwin_gitrev}/newlib newlib
+rm -rf obj-offload-nvptx-none
+mkdir obj-offload-nvptx-none
+
+cd obj-offload-nvptx-none
+CC="$CC" CXX="$CXX" CFLAGS="$OPT_FLAGS" \
+ CXXFLAGS="`echo " $OPT_FLAGS " | sed 's/ -Wall / /g;s/ -fexceptions / /g' \
+ | sed 's/ -Wformat-security / -Wformat -Wformat-security /'`" \
+ XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" \
+ ../configure --disable-bootstrap --disable-sjlj-exceptions \
+ --enable-newlib-io-long-long --with-build-time-tools=${IROOT}%{_prefix}/nvptx-none/bin \
+ --target nvptx-none --enable-as-accelerator-for=%{gcc_target_platform} \
+ --enable-languages=c,c++,fortran,lto \
+ --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \
+ --with-bugurl=http://bugzilla.openanolis.cn \
+ --enable-checking=release --with-system-zlib \
+ --with-gcc-major-version-only --without-isl
+make %{?_smp_mflags}
+cd ..
+rm -f newlib
+%endif
+
+rm -rf obj-%{gcc_target_platform}
+mkdir obj-%{gcc_target_platform}
+cd obj-%{gcc_target_platform}
+
+%if %{build_isl}
+mkdir isl-build isl-install
+ISL_FLAG_PIC=-fpic
+cd isl-build
+sed -i 's|libisl|libgcc12privateisl|g' \
+ ../../isl-%{isl_version}/Makefile.{am,in}
+../../isl-%{isl_version}/configure \
+ CC=/usr/bin/gcc CXX=/usr/bin/g++ \
+ CFLAGS="${CFLAGS:-%optflags} $ISL_FLAG_PIC" --prefix=`cd ..; pwd`/isl-install
+make %{?_smp_mflags}
+make install
+cd ../isl-install/lib
+rm libgcc12privateisl.so{,.15}
+mv libgcc12privateisl.so.15.3.0 libisl.so.15
+ln -sf libisl.so.15 libisl.so
+cd ../..
+%endif
+
+enablelgo=
+enablelada=
+enablelobjc=
+enableld=
+%if %{build_objc}
+enablelobjc=,objc,obj-c++
+%endif
+%if %{build_ada}
+enablelada=,ada
+%endif
+%if %{build_go}
+enablelgo=,go
+%endif
+%if %{build_d}
+enableld=,d
+%endif
+CONFIGURE_OPTS="\
+ --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \
+ --with-bugurl=http://bugzilla.openanolis.cn \
+ --enable-shared --enable-threads=posix --enable-checking=release \
+ --disable-multilib \
+ --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions \
+ --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only \
+ --enable-libstdcxx-backtrace \
+ --with-linker-hash-style=gnu \
+ --enable-plugin --enable-initfini-array \
+%if %{build_isl}
+ --with-isl=`pwd`/isl-install \
+%else
+ --without-isl \
+%endif
+%if %{build_offload_nvptx}
+ --enable-offload-targets=nvptx-none \
+ --without-cuda-driver --enable-offload-defaulted \
+%endif
+%if %{attr_ifunc}
+ --enable-gnu-indirect-function \
+%endif
+%ifarch x86_64
+ --enable-cet \
+ --with-tune=generic \
+%endif
+%ifarch x86_64
+ --with-arch_64=x86-64-v2 \
+ --with-arch_32=x86-64 \
+%endif
+ --build=%{gcc_target_platform} \
+ --with-build-config=bootstrap-lto --enable-link-serialization=1 \
+ "
+
+CC="$CC" CXX="$CXX" CFLAGS="$OPT_FLAGS" \
+ CXXFLAGS="`echo " $OPT_FLAGS " | sed 's/ -Wall / /g;s/ -fexceptions / /g' \
+ | sed 's/ -Wformat-security / -Wformat -Wformat-security /'`" \
+ XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" \
+ ../configure --enable-bootstrap \
+ --enable-languages=c,c++,fortran${enablelobjc}${enablelada}${enablelgo}${enableld},lto \
+ $CONFIGURE_OPTS
+
+make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" LDFLAGS_FOR_TARGET=-Wl,-z,relro,-z,now profiledbootstrap
+
+CC="`%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-cc`"
+CXX="`%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-cxx` `%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-includes`"
+
+# Build libgccjit separately, so that normal compiler binaries aren't -fpic
+# unnecessarily.
+mkdir objlibgccjit
+cd objlibgccjit
+CC="$CC" CXX="$CXX" CFLAGS="$OPT_FLAGS" \
+ CXXFLAGS="`echo " $OPT_FLAGS " | sed 's/ -Wall / /g;s/ -fexceptions / /g' \
+ | sed 's/ -Wformat-security / -Wformat -Wformat-security /'`" \
+ XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" \
+ ../../configure --disable-bootstrap --enable-host-shared \
+ --enable-languages=jit $CONFIGURE_OPTS
+make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" all-gcc
+cp -a gcc/libgccjit.so* ../gcc/
+cd ../gcc/
+ln -sf xgcc %{gcc_target_platform}-gcc-%{gcc_major}
+cp -a Makefile{,.orig}
+sed -i -e '/^CHECK_TARGETS/s/$/ check-jit/' Makefile
+touch -r Makefile.orig Makefile
+rm Makefile.orig
+make jit.sphinx.html
+make jit.sphinx.install-html jit_htmldir=`pwd`/../../rpm.doc/libgccjit-devel/html
+cd ..
+
+%if %{build_isl}
+cp -a isl-install/lib/libisl.so.15 gcc/
+%endif
+
+# Make generated man pages even if Pod::Man is not new enough
+perl -pi -e 's/head3/head2/' ../contrib/texi2pod.pl
+for i in ../gcc/doc/*.texi; do
+ cp -a $i $i.orig; sed 's/ftable/table/' $i.orig > $i
+done
+make -C gcc generated-manpages
+for i in ../gcc/doc/*.texi; do mv -f $i.orig $i; done
+
+# Make generated doxygen pages.
+%if %{build_libstdcxx_docs}
+cd %{gcc_target_platform}/libstdc++-v3
+make doc-html-doxygen
+make doc-man-doxygen
+cd ../..
+%endif
+
+# Copy various doc files here and there
+cd ..
+mkdir -p rpm.doc/gfortran rpm.doc/objc rpm.doc/gdc rpm.doc/libphobos
+mkdir -p rpm.doc/go rpm.doc/libgo rpm.doc/libquadmath rpm.doc/libitm
+mkdir -p rpm.doc/changelogs/{gcc/cp,gcc/ada,gcc/jit,libstdc++-v3,libobjc,libgomp,libcc1,libatomic,libsanitizer}
+
+for i in {gcc,gcc/cp,gcc/ada,gcc/jit,libstdc++-v3,libobjc,libgomp,libcc1,libatomic,libsanitizer}/ChangeLog*; do
+ cp -p $i rpm.doc/changelogs/$i
+done
+
+(cd gcc/fortran; for i in ChangeLog*; do
+ cp -p $i ../../rpm.doc/gfortran/$i
+done)
+(cd libgfortran; for i in ChangeLog*; do
+ cp -p $i ../rpm.doc/gfortran/$i.libgfortran
+done)
+%if %{build_objc}
+(cd libobjc; for i in README*; do
+ cp -p $i ../rpm.doc/objc/$i.libobjc
+done)
+%endif
+%if %{build_d}
+(cd gcc/d; for i in ChangeLog*; do
+ cp -p $i ../../rpm.doc/gdc/$i.gdc
+done)
+(cd libphobos; for i in ChangeLog*; do
+ cp -p $i ../rpm.doc/libphobos/$i.libphobos
+done
+cp -a src/LICENSE*.txt libdruntime/LICENSE.txt ../rpm.doc/libphobos/)
+%endif
+%if %{build_libquadmath}
+(cd libquadmath; for i in ChangeLog* COPYING.LIB; do
+ cp -p $i ../rpm.doc/libquadmath/$i.libquadmath
+done)
+%endif
+%if %{build_libitm}
+(cd libitm; for i in ChangeLog*; do
+ cp -p $i ../rpm.doc/libitm/$i.libitm
+done)
+%endif
+%if %{build_go}
+(cd gcc/go; for i in README* ChangeLog*; do
+ cp -p $i ../../rpm.doc/go/$i
+done)
+(cd libgo; for i in LICENSE* PATENTS* README; do
+ cp -p $i ../rpm.doc/libgo/$i.libgo
+done)
+%endif
+
+rm -f rpm.doc/changelogs/gcc/ChangeLog.[1-9]
+find rpm.doc -name \*ChangeLog\* | xargs bzip2 -9
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}
+
+%if %{build_offload_nvptx}
+cd nvptx-tools-%{nvptx_tools_gitrev}
+cd obj-%{gcc_target_platform}
+make install prefix=%{buildroot}%{_prefix}
+cd ../..
+
+ln -sf newlib-cygwin-%{newlib_cygwin_gitrev}/newlib newlib
+cd obj-offload-nvptx-none
+make prefix=%{buildroot}%{_prefix} mandir=%{buildroot}%{_mandir} \
+ infodir=%{buildroot}%{_infodir} install
+rm -rf %{buildroot}%{_prefix}/libexec/gcc/nvptx-none/%{gcc_major}/install-tools
+rm -rf %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none/{install-tools,plugin,cc1,cc1plus,f951}
+rm -rf %{buildroot}%{_infodir} %{buildroot}%{_mandir}/man7 %{buildroot}%{_prefix}/share/locale
+rm -rf %{buildroot}%{_prefix}/lib/gcc/nvptx-none/%{gcc_major}/{install-tools,plugin}
+rm -rf %{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none/{install-tools,plugin,include-fixed}
+rm -rf %{buildroot}%{_prefix}/%{_lib}/libc[cp]1*
+mv -f %{buildroot}%{_prefix}/nvptx-none/lib/*.{a,spec} %{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none/
+mv -f %{buildroot}%{_prefix}/nvptx-none/lib/mgomp/*.{a,spec} %{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none/mgomp/
+mv -f %{buildroot}%{_prefix}/lib/gcc/nvptx-none/%{gcc_major}/*.a %{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none/
+mv -f %{buildroot}%{_prefix}/lib/gcc/nvptx-none/%{gcc_major}/mgomp/*.a %{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none/mgomp/
+find %{buildroot}%{_prefix}/lib/gcc/nvptx-none %{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none \
+ %{buildroot}%{_prefix}/nvptx-none/lib -name \*.la | xargs rm
+cd ..
+rm -f newlib
+%endif
+
+cd obj-%{gcc_target_platform}
+
+TARGET_PLATFORM=%{gcc_target_platform}
+
+# There are some MP bugs in libstdc++ Makefiles
+make -C %{gcc_target_platform}/libstdc++-v3
+
+make prefix=%{buildroot}%{_prefix} mandir=%{buildroot}%{_mandir} \
+ infodir=%{buildroot}%{_infodir} install
+%if %{build_ada}
+chmod 644 %{buildroot}%{_infodir}/gnat*
+%endif
+
+FULLPATH=%{buildroot}%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+FULLEPATH=%{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+
+%if %{build_isl}
+cp -a isl-install/lib/libisl.so.15 $FULLPATH/
+%endif
+
+# fix some things
+ln -sf gcc %{buildroot}%{_prefix}/bin/cc
+rm -f %{buildroot}%{_prefix}/lib/cpp
+ln -sf ../bin/cpp %{buildroot}/%{_prefix}/lib/cpp
+ln -sf gfortran %{buildroot}%{_prefix}/bin/f95
+rm -f %{buildroot}%{_infodir}/dir
+gzip -9 %{buildroot}%{_infodir}/*.info*
+ln -sf gcc %{buildroot}%{_prefix}/bin/gnatgcc
+mkdir -p %{buildroot}%{_fmoddir}
+
+%if %{build_go}
+mv %{buildroot}%{_prefix}/bin/go{,.gcc}
+mv %{buildroot}%{_prefix}/bin/gofmt{,.gcc}
+ln -sf /etc/alternatives/go %{buildroot}%{_prefix}/bin/go
+ln -sf /etc/alternatives/gofmt %{buildroot}%{_prefix}/bin/gofmt
+%endif
+
+cxxconfig="`find %{gcc_target_platform}/libstdc++-v3/include -name c++config.h`"
+for i in `find %{gcc_target_platform}/[36]*/libstdc++-v3/include -name c++config.h 2>/dev/null`; do
+ if ! diff -up $cxxconfig $i; then
+ cat > %{buildroot}%{_prefix}/include/c++/%{gcc_major}/%{gcc_target_platform}/bits/c++config.h <
+#if __WORDSIZE == 32
+%ifarch %{multilib_64_archs}
+`cat $(find %{gcc_target_platform}/32/libstdc++-v3/include -name c++config.h)`
+%else
+`cat $(find %{gcc_target_platform}/libstdc++-v3/include -name c++config.h)`
+%endif
+#else
+%ifarch %{multilib_64_archs}
+`cat $(find %{gcc_target_platform}/libstdc++-v3/include -name c++config.h)`
+%else
+`cat $(find %{gcc_target_platform}/64/libstdc++-v3/include -name c++config.h)`
+%endif
+#endif
+#endif
+EOF
+ break
+ fi
+done
+
+for f in `find %{buildroot}%{_prefix}/include/c++/%{gcc_major}/%{gcc_target_platform}/ -name c++config.h`; do
+ for i in 1 2 4 8; do
+ sed -i -e 's/#define _GLIBCXX_ATOMIC_BUILTINS_'$i' 1/#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_'$i'\
+&\
+#endif/' $f
+ done
+done
+
+# Nuke bits/*.h.gch dirs
+# 1) there is no bits/*.h header installed, so when gch file can't be
+# used, compilation fails
+# 2) sometimes it is hard to match the exact options used for building
+# libstdc++-v3 or they aren't desirable
+# 3) there are multilib issues, conflicts etc. with this
+# 4) it is huge
+# People can always precompile on their own whatever they want, but
+# shipping this for everybody is unnecessary.
+rm -rf %{buildroot}%{_prefix}/include/c++/%{gcc_major}/%{gcc_target_platform}/bits/*.h.gch
+
+%if %{build_libstdcxx_docs}
+libstdcxx_doc_builddir=%{gcc_target_platform}/libstdc++-v3/doc/doxygen
+mkdir -p ../rpm.doc/libstdc++-v3
+cp -r -p ../libstdc++-v3/doc/html ../rpm.doc/libstdc++-v3/html
+cp -r -p $libstdcxx_doc_builddir/html ../rpm.doc/libstdc++-v3/html/api
+mkdir -p %{buildroot}%{_mandir}/man3
+cp -r -p $libstdcxx_doc_builddir/man/man3/* %{buildroot}%{_mandir}/man3/
+find ../rpm.doc/libstdc++-v3 -name \*~ | xargs rm
+%endif
+
+FULLLSUBDIR=
+if [ -n "$FULLLSUBDIR" ]; then
+ FULLLPATH=$FULLPATH/$FULLLSUBDIR
+ mkdir -p $FULLLPATH
+else
+ FULLLPATH=$FULLPATH
+fi
+
+find %{buildroot} -name \*.la | xargs rm -f
+
+mv %{buildroot}%{_prefix}/%{_lib}/libgfortran.spec $FULLPATH/
+%if %{build_d}
+mv %{buildroot}%{_prefix}/%{_lib}/libgphobos.spec $FULLPATH/
+%endif
+%if %{build_libitm}
+mv %{buildroot}%{_prefix}/%{_lib}/libitm.spec $FULLPATH/
+%endif
+%if %{build_libasan}
+mv %{buildroot}%{_prefix}/%{_lib}/libsanitizer.spec $FULLPATH/
+%endif
+
+mkdir -p %{buildroot}/%{_lib}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgcc_s.so.1 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1
+chmod 755 %{buildroot}/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1
+ln -sf libgcc_s-%{gcc_major}-%{DATE}.so.1 %{buildroot}/%{_lib}/libgcc_s.so.1
+rm -f $FULLPATH/libgcc_s.so
+echo '/* GNU ld script
+ Use the shared library, but some functions are only in
+ the static library, so try that secondarily. */
+OUTPUT_FORMAT('`gcc -Wl,--print-output-format -nostdlib -r -o /dev/null`')
+GROUP ( /%{_lib}/libgcc_s.so.1 libgcc.a )' > $FULLPATH/libgcc_s.so
+%ifarch %{multilib_64_archs}
+%ifarch x86_64
+rm -f $FULLPATH/64/libgcc_s.so
+echo '/* GNU ld script
+ Use the shared library, but some functions are only in
+ the static library, so try that secondarily. */
+OUTPUT_FORMAT('`gcc -m32 -Wl,--print-output-format -nostdlib -r -o /dev/null`')
+GROUP ( /lib/libgcc_s.so.1 libgcc.a )' > $FULLPATH/32/libgcc_s.so
+%else
+ln -sf /lib/libgcc_s.so.1 $FULLPATH/32/libgcc_s.so
+%endif
+%endif
+
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgomp.spec $FULLPATH/
+
+%if %{build_ada}
+mv -f $FULLPATH/adalib/libgnarl-*.so %{buildroot}%{_prefix}/%{_lib}/
+mv -f $FULLPATH/adalib/libgnat-*.so %{buildroot}%{_prefix}/%{_lib}/
+rm -f $FULLPATH/adalib/libgnarl.so* $FULLPATH/adalib/libgnat.so*
+%endif
+
+mkdir -p %{buildroot}%{_prefix}/libexec/getconf
+if gcc/xgcc -B gcc/ -E -P -dD -xc /dev/null | grep '__LONG_MAX__.*\(2147483647\|0x7fffffff\($\|[LU]\)\)'; then
+ ln -sf POSIX_V6_ILP32_OFF32 %{buildroot}%{_prefix}/libexec/getconf/default
+else
+ ln -sf POSIX_V6_LP64_OFF64 %{buildroot}%{_prefix}/libexec/getconf/default
+fi
+
+mkdir -p %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++*gdb.py* \
+ %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/
+pushd ../libstdc++-v3/python
+for i in `find . -name \*.py`; do
+ touch -r $i %{buildroot}%{_prefix}/share/gcc-%{gcc_major}/python/$i
+done
+touch -r hook.in %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/libstdc++*gdb.py
+popd
+for f in `find %{buildroot}%{_prefix}/share/gcc-%{gcc_major}/python/ \
+ %{buildroot}%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/ -name \*.py`; do
+ r=${f/$RPM_BUILD_ROOT/}
+ %{__python3} -c 'import py_compile; py_compile.compile("'$f'", dfile="'$r'")'
+ %{__python3} -O -c 'import py_compile; py_compile.compile("'$f'", dfile="'$r'")'
+done
+
+rm -f $FULLEPATH/libgccjit.so
+cp -a objlibgccjit/gcc/libgccjit.so* %{buildroot}%{_prefix}/%{_lib}/
+cp -a ../gcc/jit/libgccjit*.h %{buildroot}%{_prefix}/include/
+/usr/bin/install -c -m 644 objlibgccjit/gcc/doc/libgccjit.info %{buildroot}/%{_infodir}/
+gzip -9 %{buildroot}/%{_infodir}/libgccjit.info
+
+pushd $FULLPATH
+if [ "%{_lib}" = "lib" ]; then
+%if %{build_objc}
+ln -sf ../../../libobjc.so.4 libobjc.so
+%endif
+ln -sf ../../../libstdc++.so.6.*[0-9] libstdc++.so
+ln -sf ../../../libgfortran.so.5.* libgfortran.so
+ln -sf ../../../libgomp.so.1.* libgomp.so
+%if %{build_go}
+ln -sf ../../../libgo.so.21.* libgo.so
+%endif
+%if %{build_libquadmath}
+ln -sf ../../../libquadmath.so.0.* libquadmath.so
+%endif
+%if %{build_d}
+ln -sf ../../../libgdruntime.so.3.* libgdruntime.so
+ln -sf ../../../libgphobos.so.3.* libgphobos.so
+%endif
+%if %{build_libitm}
+ln -sf ../../../libitm.so.1.* libitm.so
+%endif
+%if %{build_libatomic}
+ln -sf ../../../libatomic.so.1.* libatomic.so
+%endif
+%if %{build_libasan}
+ln -sf ../../../libasan.so.8.* libasan.so
+mv ../../../libasan_preinit.o libasan_preinit.o
+%endif
+%if %{build_libubsan}
+ln -sf ../../../libubsan.so.1.* libubsan.so
+%endif
+else
+%if %{build_objc}
+ln -sf ../../../../%{_lib}/libobjc.so.4 libobjc.so
+%endif
+ln -sf ../../../../%{_lib}/libstdc++.so.6.*[0-9] libstdc++.so
+ln -sf ../../../../%{_lib}/libgfortran.so.5.* libgfortran.so
+ln -sf ../../../../%{_lib}/libgomp.so.1.* libgomp.so
+%if %{build_go}
+ln -sf ../../../../%{_lib}/libgo.so.21.* libgo.so
+%endif
+%if %{build_libquadmath}
+ln -sf ../../../../%{_lib}/libquadmath.so.0.* libquadmath.so
+%endif
+%if %{build_d}
+ln -sf ../../../../%{_lib}/libgdruntime.so.3.* libgdruntime.so
+ln -sf ../../../../%{_lib}/libgphobos.so.3.* libgphobos.so
+%endif
+%if %{build_libitm}
+ln -sf ../../../../%{_lib}/libitm.so.1.* libitm.so
+%endif
+%if %{build_libatomic}
+ln -sf ../../../../%{_lib}/libatomic.so.1.* libatomic.so
+%endif
+%if %{build_libasan}
+ln -sf ../../../../%{_lib}/libasan.so.8.* libasan.so
+mv ../../../../%{_lib}/libasan_preinit.o libasan_preinit.o
+%endif
+%if %{build_libubsan}
+ln -sf ../../../../%{_lib}/libubsan.so.1.* libubsan.so
+%endif
+%if %{build_libtsan}
+rm -f libtsan.so
+echo 'INPUT ( %{_prefix}/%{_lib}/'`echo ../../../../%{_lib}/libtsan.so.2.* | sed 's,^.*libt,libt,'`' )' > libtsan.so
+mv ../../../../%{_lib}/libtsan_preinit.o libtsan_preinit.o
+%endif
+%if %{build_liblsan}
+rm -f liblsan.so
+echo 'INPUT ( %{_prefix}/%{_lib}/'`echo ../../../../%{_lib}/liblsan.so.0.* | sed 's,^.*libl,libl,'`' )' > liblsan.so
+mv ../../../../%{_lib}/liblsan_preinit.o liblsan_preinit.o
+%endif
+fi
+mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++fs.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libstdc++_libbacktrace.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libsupc++.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgfortran.*a $FULLLPATH/
+%if %{build_objc}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libobjc.*a .
+%endif
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgomp.*a .
+%if %{build_libquadmath}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libquadmath.*a $FULLLPATH/
+%endif
+%if %{build_d}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgdruntime.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgphobos.*a $FULLLPATH/
+%endif
+%if %{build_libitm}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libitm.*a $FULLLPATH/
+%endif
+%if %{build_libatomic}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libatomic.*a $FULLLPATH/
+%endif
+%if %{build_libasan}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libasan.*a $FULLLPATH/
+%endif
+%if %{build_libubsan}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libubsan.*a $FULLLPATH/
+%endif
+%if %{build_libtsan}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libtsan.*a $FULLPATH/
+%endif
+%if %{build_liblsan}
+mv -f %{buildroot}%{_prefix}/%{_lib}/liblsan.*a $FULLPATH/
+%endif
+%if %{build_go}
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgo.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgobegin.*a $FULLLPATH/
+mv -f %{buildroot}%{_prefix}/%{_lib}/libgolibbegin.*a $FULLLPATH/
+%endif
+
+%if %{build_ada}
+%ifarch %{multilib_64_archs}
+rm -rf $FULLPATH/32/ada{include,lib}
+%endif
+if [ "$FULLPATH" != "$FULLLPATH" ]; then
+mv -f $FULLPATH/ada{include,lib} $FULLLPATH/
+pushd $FULLLPATH/adalib
+if [ "%{_lib}" = "lib" ]; then
+ln -sf ../../../../../libgnarl-*.so libgnarl.so
+ln -sf ../../../../../libgnarl-*.so libgnarl-12.so
+ln -sf ../../../../../libgnat-*.so libgnat.so
+ln -sf ../../../../../libgnat-*.so libgnat-12.so
+else
+ln -sf ../../../../../../%{_lib}/libgnarl-*.so libgnarl.so
+ln -sf ../../../../../../%{_lib}/libgnarl-*.so libgnarl-12.so
+ln -sf ../../../../../../%{_lib}/libgnat-*.so libgnat.so
+ln -sf ../../../../../../%{_lib}/libgnat-*.so libgnat-12.so
+fi
+popd
+else
+pushd $FULLPATH/adalib
+if [ "%{_lib}" = "lib" ]; then
+ln -sf ../../../../libgnarl-*.so libgnarl.so
+ln -sf ../../../../libgnarl-*.so libgnarl-12.so
+ln -sf ../../../../libgnat-*.so libgnat.so
+ln -sf ../../../../libgnat-*.so libgnat-12.so
+else
+ln -sf ../../../../../%{_lib}/libgnarl-*.so libgnarl.so
+ln -sf ../../../../../%{_lib}/libgnarl-*.so libgnarl-12.so
+ln -sf ../../../../../%{_lib}/libgnat-*.so libgnat.so
+ln -sf ../../../../../%{_lib}/libgnat-*.so libgnat-12.so
+fi
+popd
+fi
+%endif
+
+%ifarch %{multilib_64_archs}
+mkdir -p 32
+%if %{build_objc}
+ln -sf ../../../../libobjc.so.4 32/libobjc.so
+%endif
+ln -sf ../`echo ../../../../lib64/libstdc++.so.6.*[0-9] | sed s~/../lib64/~/~` 32/libstdc++.so
+ln -sf ../`echo ../../../../lib64/libgfortran.so.5.* | sed s~/../lib64/~/~` 32/libgfortran.so
+ln -sf ../`echo ../../../../lib64/libgomp.so.1.* | sed s~/../lib64/~/~` 32/libgomp.so
+%if %{build_go}
+rm -f libgo.so
+echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgo.so.21.* | sed 's,^.*libg,libg,'`' )' > libgo.so
+echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgo.so.21.* | sed 's,^.*libg,libg,'`' )' > 32/libgo.so
+%endif
+%if %{build_libquadmath}
+rm -f libquadmath.so
+echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libquadmath.so.0.* | sed 's,^.*libq,libq,'`' )' > libquadmath.so
+echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libquadmath.so.0.* | sed 's,^.*libq,libq,'`' )' > 32/libquadmath.so
+%endif
+%if %{build_d}
+rm -f libgdruntime.so libgphobos.so
+echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgdruntime.so.3.* | sed 's,^.*libg,libg,'`' )' > libgdruntime.so
+echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgdruntime.so.3.* | sed 's,^.*libg,libg,'`' )' > 32/libgdruntime.so
+echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libgphobos.so.3.* | sed 's,^.*libg,libg,'`' )' > libgphobos.so
+echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libgphobos.so.3.* | sed 's,^.*libg,libg,'`' )' > 32/libgphobos.so
+%endif
+%if %{build_libitm}
+rm -f libitm.so
+echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libitm.so.1.* | sed 's,^.*libi,libi,'`' )' > libitm.so
+echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libitm.so.1.* | sed 's,^.*libi,libi,'`' )' > 32/libitm.so
+%endif
+%if %{build_libatomic}
+rm -f libatomic.so
+echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libatomic.so.1.* | sed 's,^.*liba,liba,'`' )' > libatomic.so
+echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libatomic.so.1.* | sed 's,^.*liba,liba,'`' )' > 32/libatomic.so
+%endif
+%if %{build_libasan}
+rm -f libasan.so
+echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libasan.so.8.* | sed 's,^.*liba,liba,'`' )' > libasan.so
+echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libasan.so.8.* | sed 's,^.*liba,liba,'`' )' > 32/libasan.so
+mv ../../../../lib/libasan_preinit.o 32/libasan_preinit.o
+%endif
+%if %{build_libubsan}
+rm -f libubsan.so
+echo 'INPUT ( %{_prefix}/lib64/'`echo ../../../../lib64/libubsan.so.1.* | sed 's,^.*libu,libu,'`' )' > libubsan.so
+echo 'INPUT ( %{_prefix}/lib/'`echo ../../../../lib64/libubsan.so.1.* | sed 's,^.*libu,libu,'`' )' > 32/libubsan.so
+%endif
+%if %{build_objc}
+mv -f %{buildroot}%{_prefix}/lib/libobjc.*a 32/
+%endif
+mv -f %{buildroot}%{_prefix}/lib/libgomp.*a 32/
+%endif
+%ifarch %{multilib_64_archs}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgfortran.a 32/libgfortran.a
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libstdc++.a 32/libstdc++.a
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libstdc++fs.a 32/libstdc++fs.a
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libstdc++_libbacktrace.a 32/libstdc++_libbacktrace.a
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libsupc++.a 32/libsupc++.a
+%if %{build_libquadmath}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libquadmath.a 32/libquadmath.a
+%endif
+%if %{build_d}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgdruntime.a 32/libgdruntime.a
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgphobos.a 32/libgphobos.a
+%endif
+%if %{build_libitm}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libitm.a 32/libitm.a
+%endif
+%if %{build_libatomic}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libatomic.a 32/libatomic.a
+%endif
+%if %{build_libasan}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libasan.a 32/libasan.a
+%endif
+%if %{build_libubsan}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libubsan.a 32/libubsan.a
+%endif
+%if %{build_go}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgo.a 32/libgo.a
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgobegin.a 32/libgobegin.a
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/libgolibbegin.a 32/libgolibbegin.a
+%endif
+%if %{build_ada}
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/adainclude 32/adainclude
+ln -sf ../../../%{multilib_32_arch}-%{_vendor}-%{_target_os}/%{gcc_major}/adalib 32/adalib
+%endif
+%endif
+
+# If we are building a debug package then copy all of the static archives
+# into the debug directory to keep them as unstripped copies.
+%if 0%{?_enable_debug_packages}
+for d in . $FULLLSUBDIR; do
+ mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/debug%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/$d
+ for f in `find $d -maxdepth 1 -a \
+ \( -name libasan.a -o -name libatomic.a \
+ -o -name libcaf_single.a \
+ -o -name libgcc.a -o -name libgcc_eh.a \
+ -o -name libgcov.a -o -name libgfortran.a \
+ -o -name libgo.a -o -name libgobegin.a \
+ -o -name libgolibbegin.a -o -name libgomp.a \
+ -o -name libitm.a -o -name liblsan.a \
+ -o -name libobjc.a -o -name libgdruntime.a -o -name libgphobos.a \
+ -o -name libquadmath.a -o -name libstdc++.a \
+ -o -name libstdc++fs.a -o -name libstdc++_libbacktrace.a -o -name libsupc++.a \
+ -o -name libtsan.a -o -name libubsan.a \) -a -type f`; do
+ cp -a $f $RPM_BUILD_ROOT%{_prefix}/lib/debug%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/$d/
+ done
+done
+%endif
+
+# Strip debug info from Fortran/ObjC/Java static libraries
+strip -g `find . \( -name libgfortran.a -o -name libobjc.a -o -name libgomp.a \
+ -o -name libgcc.a -o -name libgcov.a -o -name libquadmath.a \
+ -o -name libgdruntime.a -o -name libgphobos.a \
+ -o -name libitm.a -o -name libgo.a -o -name libcaf\*.a \
+ -o -name libatomic.a -o -name libasan.a -o -name libtsan.a \
+ -o -name libubsan.a -o -name liblsan.a -o -name libcc1.a \) \
+ -a -type f`
+popd
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgfortran.so.5.*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgomp.so.1.*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libcc1.so.0.*
+%if %{build_libquadmath}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libquadmath.so.0.*
+%endif
+%if %{build_d}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgdruntime.so.3.*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgphobos.so.3.*
+%endif
+%if %{build_libitm}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libitm.so.1.*
+%endif
+%if %{build_libatomic}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libatomic.so.1.*
+%endif
+%if %{build_libasan}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libasan.so.8.*
+%endif
+%if %{build_libubsan}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libubsan.so.1.*
+%endif
+%if %{build_libtsan}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libtsan.so.2.*
+%endif
+%if %{build_liblsan}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/liblsan.so.0.*
+%endif
+%if %{build_go}
+# Avoid stripping these libraries and binaries.
+chmod 644 %{buildroot}%{_prefix}/%{_lib}/libgo.so.21.*
+chmod 644 %{buildroot}%{_prefix}/bin/go.gcc
+chmod 644 %{buildroot}%{_prefix}/bin/gofmt.gcc
+chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo
+chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/buildid
+chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json
+chmod 644 %{buildroot}%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet
+%endif
+%if %{build_objc}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libobjc.so.4.*
+%endif
+
+%if %{build_ada}
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgnarl*so*
+chmod 755 %{buildroot}%{_prefix}/%{_lib}/libgnat*so*
+%endif
+
+mv $FULLPATH/include-fixed/syslimits.h $FULLPATH/include/syslimits.h
+mv $FULLPATH/include-fixed/limits.h $FULLPATH/include/limits.h
+for h in `find $FULLPATH/include -name \*.h`; do
+ if grep -q 'It has been auto-edited by fixincludes from' $h; then
+ rh=`grep -A2 'It has been auto-edited by fixincludes from' $h | tail -1 | sed 's|^.*"\(.*\)".*$|\1|'`
+ diff -up $rh $h || :
+ rm -f $h
+ fi
+done
+
+cat > %{buildroot}%{_prefix}/bin/c89 <<"EOF"
+#!/bin/sh
+fl="-std=c89"
+for opt; do
+ case "$opt" in
+ -ansi|-std=c89|-std=iso9899:1990) fl="";;
+ -std=*) echo "`basename $0` called with non ANSI/ISO C option $opt" >&2
+ exit 1;;
+ esac
+done
+exec gcc $fl ${1+"$@"}
+EOF
+cat > %{buildroot}%{_prefix}/bin/c99 <<"EOF"
+#!/bin/sh
+fl="-std=c99"
+for opt; do
+ case "$opt" in
+ -std=c99|-std=iso9899:1999) fl="";;
+ -std=*) echo "`basename $0` called with non ISO C99 option $opt" >&2
+ exit 1;;
+ esac
+done
+exec gcc $fl ${1+"$@"}
+EOF
+chmod 755 %{buildroot}%{_prefix}/bin/c?9
+
+cd ..
+%find_lang %{name}
+%find_lang cpplib
+
+# Remove binaries we will not be including, so that they don't end up in
+# gcc-debuginfo
+rm -f %{buildroot}%{_prefix}/%{_lib}/{libffi*,libiberty.a} || :
+rm -f $FULLEPATH/install-tools/{mkheaders,fixincl}
+rm -f %{buildroot}%{_prefix}/lib/{32,64}/libiberty.a
+rm -f %{buildroot}%{_prefix}/%{_lib}/libssp*
+rm -f %{buildroot}%{_prefix}/%{_lib}/libvtv* || :
+rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gfortran || :
+rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gccgo || :
+rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcj || :
+rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcc-ar || :
+rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcc-nm || :
+rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gcc-ranlib || :
+rm -f %{buildroot}%{_prefix}/bin/%{_target_platform}-gdc || :
+
+%ifarch %{multilib_64_archs}
+# Remove libraries for the other arch on multilib arches
+rm -f %{buildroot}%{_prefix}/lib/lib*.so*
+rm -f %{buildroot}%{_prefix}/lib/lib*.a
+rm -f %{buildroot}/lib/libgcc_s*.so*
+%if %{build_go}
+rm -rf %{buildroot}%{_prefix}/lib/go/%{gcc_major}/%{gcc_target_platform}
+ln -sf %{multilib_32_arch}-%{_vendor}-%{_target_os} %{buildroot}%{_prefix}/lib/go/%{gcc_major}/%{gcc_target_platform}
+%endif
+%endif
+
+rm -f %{buildroot}%{mandir}/man3/ffi*
+
+# Help plugins find out nvra.
+echo gcc-%{version}-%{release}.%{_arch} > $FULLPATH/rpmver
+
+# Add symlink to lto plugin in the binutils plugin directory.
+%{__mkdir_p} %{buildroot}%{_libdir}/bfd-plugins/
+ln -s ../../libexec/gcc/%{gcc_target_platform}/%{gcc_major}/liblto_plugin.so \
+ %{buildroot}%{_libdir}/bfd-plugins/
+
+%check
+cd obj-%{gcc_target_platform}
+
+# run the tests.
+LC_ALL=C make %{?_smp_mflags} -k check ALT_CC_UNDER_TEST=gcc ALT_CXX_UNDER_TEST=g++ \
+ RUNTESTFLAGS="--target_board=unix/'{,-fstack-protector-strong}'" || :
+if [ -f %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/annobin.so ]; then
+ # Test whether current annobin plugin won't fail miserably with the newly built gcc.
+ echo -e '#include \nint main () { printf ("Hello, world!\\n"); return 0; }' > annobin-test.c
+ echo -e '#include \nint main () { std::cout << "Hello, world!" << std::endl; return 0; }' > annobin-test.C
+ `%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-cc` \
+ -O2 -g -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS \
+ -fexceptions -fstack-protector-strong -grecord-gcc-switches -o annobin-test{c,.c} \
+ -Wl,-rpath,%{gcc_target_platform}/libgcc/ \
+ -fplugin=%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/annobin.so \
+ 2> ANNOBINOUT1 || echo Annobin test 1 FAIL > ANNOBINOUT2;
+ `%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-cxx` \
+ `%{gcc_target_platform}/libstdc++-v3/scripts/testsuite_flags --build-includes` \
+ -O2 -g -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS \
+ -fexceptions -fstack-protector-strong -grecord-gcc-switches -o annobin-test{C,.C} \
+ -Wl,-rpath,%{gcc_target_platform}/libgcc/:%{gcc_target_platform}/libstdc++-v3/src/.libs/ \
+ -fplugin=%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/annobin.so \
+ -B %{gcc_target_platform}/libstdc++-v3/src/.libs/ \
+ 2> ANNOBINOUT3 || echo Annobin test 2 FAIL > ANNOBINOUT4;
+ [ -f ./annobin-testc ] || echo Annobin test 1 MISSING > ANNOBINOUT5;
+ [ -f ./annobin-testc ] && \
+ ( ./annobin-testc > ANNOBINRES1 2>&1 || echo Annobin test 1 RUNFAIL > ANNOBINOUT6 );
+ [ -f ./annobin-testC ] || echo Annobin test 2 MISSING > ANNOBINOUT7;
+ [ -f ./annobin-testC ] && \
+ ( ./annobin-testC > ANNOBINRES2 2>&1 || echo Annobin test 2 RUNFAIL > ANNOBINOUT8 );
+ cat ANNOBINOUT[1-8] > ANNOBINOUT
+ touch ANNOBINRES1 ANNOBINRES2
+ [ -s ANNOBINOUT ] && echo Annobin testing FAILed > ANNOBINRES
+ cat ANNOBINOUT ANNOBINRES[12] >> ANNOBINRES
+ rm -f ANNOBINOUT* ANNOBINRES[12] annobin-test{c,C}
+fi
+echo ====================TESTING=========================
+( LC_ALL=C ../contrib/test_summary || : ) 2>&1 | sed -n '/^cat.*EOF/,/^EOF/{/^cat.*EOF/d;/^EOF/d;/^LAST_UPDATED:/d;p;}'
+[ -f ANNOBINRES ] && cat ANNOBINRES
+echo ====================TESTING END=====================
+mkdir testlogs-%{_target_platform}-%{version}-%{release}
+for i in `find . -name \*.log | grep -F testsuite/ | grep -v 'config.log\|acats.*/tests/'`; do
+ ln $i testlogs-%{_target_platform}-%{version}-%{release}/ || :
+done
+tar cf - testlogs-%{_target_platform}-%{version}-%{release} | xz -9e \
+ | uuencode testlogs-%{_target_platform}.tar.xz || :
+rm -rf testlogs-%{_target_platform}-%{version}-%{release}
+
+%post go
+%{_sbindir}/update-alternatives --install \
+ %{_prefix}/bin/go go %{_prefix}/bin/go.gcc 92 \
+ --slave %{_prefix}/bin/gofmt gofmt %{_prefix}/bin/gofmt.gcc
+
+%preun go
+if [ $1 = 0 ]; then
+ %{_sbindir}/update-alternatives --remove go %{_prefix}/bin/go.gcc
+fi
+
+# Because glibc Prereq's libgcc and /sbin/ldconfig
+# comes from glibc, it might not exist yet when
+# libgcc is installed
+%post -n libgcc -p
+if posix.access ("/sbin/ldconfig", "x") then
+ local pid = posix.fork ()
+ if pid == 0 then
+ posix.exec ("/sbin/ldconfig")
+ elseif pid ~= -1 then
+ posix.wait (pid)
+ end
+end
+
+%postun -n libgcc -p
+if posix.access ("/sbin/ldconfig", "x") then
+ local pid = posix.fork ()
+ if pid == 0 then
+ posix.exec ("/sbin/ldconfig")
+ elseif pid ~= -1 then
+ posix.wait (pid)
+ end
+end
+
+%ldconfig_scriptlets -n libstdc++
+
+%ldconfig_scriptlets -n libobjc
+
+%ldconfig_scriptlets -n libgfortran
+
+%ldconfig_scriptlets -n libgphobos
+
+%ldconfig_scriptlets -n libgnat
+
+%ldconfig_scriptlets -n libgomp
+
+%ldconfig_scriptlets gdb-plugin
+
+%ldconfig_scriptlets -n libgccjit
+
+%ldconfig_scriptlets -n libquadmath
+
+%ldconfig_scriptlets -n libitm
+
+%ldconfig_scriptlets -n libatomic
+
+%ldconfig_scriptlets -n libasan
+
+%ldconfig_scriptlets -n libubsan
+
+%ldconfig_scriptlets -n libtsan
+
+%ldconfig_scriptlets -n liblsan
+
+%ldconfig_scriptlets -n libgo
+
+%files -f %{name}.lang
+%{_prefix}/bin/cc
+%{_prefix}/bin/c89
+%{_prefix}/bin/c99
+%{_prefix}/bin/gcc
+%{_prefix}/bin/gcov
+%{_prefix}/bin/gcov-tool
+%{_prefix}/bin/gcov-dump
+%{_prefix}/bin/gcc-ar
+%{_prefix}/bin/gcc-nm
+%{_prefix}/bin/gcc-ranlib
+%{_prefix}/bin/lto-dump
+%{_prefix}/bin/%{gcc_target_platform}-gcc
+%{_prefix}/bin/%{gcc_target_platform}-gcc-%{gcc_major}
+%{_mandir}/man1/gcc.1*
+%{_mandir}/man1/gcov.1*
+%{_mandir}/man1/gcov-tool.1*
+%{_mandir}/man1/gcov-dump.1*
+%{_mandir}/man1/lto-dump.1*
+%{_infodir}/gcc*
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/lto1
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/lto-wrapper
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/liblto_plugin.so*
+%{_libdir}/bfd-plugins/liblto_plugin.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/rpmver
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stddef.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdarg.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdfix.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/varargs.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/float.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/limits.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdbool.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/iso646.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/syslimits.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/unwind.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/omp.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/openacc.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/acc_prof.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdint.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdint-gcc.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdalign.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdnoreturn.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/stdatomic.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/gcov.h
+%ifarch x86_64
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xmmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/emmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/pmmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/tmmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ammintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/smmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/nmmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/bmmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/wmmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/immintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avxintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/x86intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/fma4intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xopintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/lwpintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/popcntintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/bmiintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/tbmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ia32intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx2intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/bmi2intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/f16cintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/fmaintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/lzcntintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/rtmintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xtestintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/adxintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/prfchwintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/rdseedintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/fxsrintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xsaveintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xsaveoptintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512cdintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512erintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512fintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512pfintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/shaintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mm_malloc.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mm3dnow.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cpuid.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cross-stdarg.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512bwintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512dqintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512ifmaintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512ifmavlintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vbmiintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vbmivlintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vlbwintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vldqintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vlintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/clflushoptintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/clwbintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mwaitxintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xsavecintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/xsavesintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/clzerointrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/pkuintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx5124fmapsintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx5124vnniwintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vpopcntdqintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/sgxintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/gfniintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cetintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cet.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vbmi2intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vbmi2vlintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vnniintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vnnivlintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/vaesintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/vpclmulqdqintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vpopcntdqvlintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512bitalgintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/pconfigintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/wbnoinvdintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/movdirintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/waitpkgintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/cldemoteintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512bf16vlintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512bf16intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/enqcmdintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vp2intersectintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512vp2intersectvlintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/serializeintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/tsxldtrkintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amxtileintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amxint8intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/amxbf16intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/x86gprintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/uintrintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/hresetintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/keylockerintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avxvnniintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/mwaitintrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512fp16intrin.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/avx512fp16vlintrin.h
+%endif
+%ifarch aarch64
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_neon.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_acle.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_fp16.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_bf16.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/arm_sve.h
+%endif
+%if %{build_libasan}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/sanitizer
+%endif
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/collect2
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/crt*.o
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgcc.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgcov.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgcc_eh.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgcc_s.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp.spec
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgomp.so
+%if %{build_libitm}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.spec
+%endif
+%if %{build_libasan}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libsanitizer.spec
+%endif
+%if %{build_isl}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libisl.so.*
+%endif
+%ifarch %{multilib_64_archs}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/crt*.o
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgcc.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgcov.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgcc_eh.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgcc_s.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgomp.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgomp.so
+%if %{build_libquadmath}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libquadmath.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libquadmath.so
+%endif
+%if %{build_libitm}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libitm.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libitm.so
+%endif
+%if %{build_libatomic}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libatomic.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libatomic.so
+%endif
+%if %{build_libasan}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libasan.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libasan.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libasan_preinit.o
+%endif
+%if %{build_libubsan}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libubsan.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libubsan.so
+%endif
+%endif
+%if %{build_libatomic}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libatomic.so
+%endif
+%if %{build_libasan}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan_preinit.o
+%endif
+%if %{build_libubsan}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libubsan.so
+%endif
+%if %{build_libtsan}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libtsan.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libtsan_preinit.o
+%endif
+%if %{build_liblsan}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/liblsan.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/liblsan_preinit.o
+%endif
+%{_prefix}/libexec/getconf/default
+%doc gcc/README* rpm.doc/changelogs/gcc/ChangeLog*
+%{!?_licensedir:%global license %%doc}
+%license gcc/COPYING* COPYING.RUNTIME
+
+%files -n cpp -f cpplib.lang
+%{_prefix}/lib/cpp
+%{_prefix}/bin/cpp
+%{_mandir}/man1/cpp.1*
+%{_infodir}/cpp*
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cc1
+
+%files -n libgcc
+/%{_lib}/libgcc_s-%{gcc_major}-%{DATE}.so.1
+/%{_lib}/libgcc_s.so.1
+%{!?_licensedir:%global license %%doc}
+%license gcc/COPYING* COPYING.RUNTIME
+
+%files c++
+%{_prefix}/bin/%{gcc_target_platform}-*++
+%{_prefix}/bin/g++
+%{_prefix}/bin/c++
+%{_mandir}/man1/g++.1*
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cc1plus
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/g++-mapper-server
+%ifarch %{multilib_64_archs}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libstdc++.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libstdc++.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libstdc++fs.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libstdc++_libbacktrace.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libsupc++.a
+%endif
+%ifarch %{multilib_64_archs}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++.so
+%endif
+%doc rpm.doc/changelogs/gcc/cp/ChangeLog*
+
+%files -n libstdc++
+%{_prefix}/%{_lib}/libstdc++.so.6*
+%dir %{_datadir}/gdb
+%dir %{_datadir}/gdb/auto-load
+%dir %{_datadir}/gdb/auto-load/%{_prefix}
+%dir %{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/
+%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/libstdc*gdb.py*
+%{_datadir}/gdb/auto-load/%{_prefix}/%{_lib}/__pycache__
+%dir %{_prefix}/share/gcc-%{gcc_major}
+%dir %{_prefix}/share/gcc-%{gcc_major}/python
+%{_prefix}/share/gcc-%{gcc_major}/python/libstdcxx
+
+%files -n libstdc++-devel
+%dir %{_prefix}/include/c++
+%{_prefix}/include/c++/%{gcc_major}
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%ifnarch %{multilib_64_archs}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++.so
+%endif
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++fs.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++_libbacktrace.a
+%doc rpm.doc/changelogs/libstdc++-v3/ChangeLog* libstdc++-v3/README*
+
+%files -n libstdc++-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libstdc++.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libsupc++.a
+
+%if %{build_libstdcxx_docs}
+%files -n libstdc++-docs
+%{_mandir}/man3/*
+%doc rpm.doc/libstdc++-v3/html
+%endif
+
+%if %{build_objc}
+%files objc
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/objc
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cc1obj
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libobjc.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libobjc.so
+%ifarch %{multilib_64_archs}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libobjc.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libobjc.so
+%endif
+%doc rpm.doc/objc/*
+%doc libobjc/THREADS* rpm.doc/changelogs/libobjc/ChangeLog*
+
+%files objc++
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cc1objplus
+
+%files -n libobjc
+%{_prefix}/%{_lib}/libobjc.so.4*
+%endif
+
+%files gfortran
+%{_prefix}/bin/gfortran
+%{_prefix}/bin/f95
+%{_mandir}/man1/gfortran.1*
+%{_infodir}/gfortran*
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/ISO_Fortran_binding.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/omp_lib.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/omp_lib.f90
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/omp_lib.mod
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/omp_lib_kinds.mod
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/openacc.f90
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/openacc.mod
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/openacc_kinds.mod
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/openacc_lib.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_arithmetic.mod
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_exceptions.mod
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/finclude/ieee_features.mod
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/f951
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.spec
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libcaf_single.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.so
+%ifarch %{multilib_64_archs}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libcaf_single.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgfortran.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgfortran.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/finclude
+%endif
+%dir %{_fmoddir}
+%doc rpm.doc/gfortran/*
+
+%files -n libgfortran
+%{_prefix}/%{_lib}/libgfortran.so.5*
+
+%files -n libgfortran-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgfortran.a
+
+%if %{build_d}
+%files gdc
+%{_prefix}/bin/gdc
+%{_mandir}/man1/gdc.1*
+%{_infodir}/gdc*
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/d
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/d21
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgphobos.spec
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgdruntime.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgphobos.so
+%ifarch %{multilib_64_archs}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgdruntime.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgphobos.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgdruntime.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgphobos.so
+%endif
+%doc rpm.doc/gdc/*
+
+%files -n libgphobos
+%{_prefix}/%{_lib}/libgdruntime.so.3*
+%{_prefix}/%{_lib}/libgphobos.so.3*
+%doc rpm.doc/libphobos/*
+
+%files -n libgphobos-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgdruntime.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgphobos.a
+%endif
+
+%if %{build_ada}
+%files gnat
+%{_prefix}/bin/gnat
+%{_prefix}/bin/gnat[^i]*
+%{_infodir}/gnat*
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%ifarch %{multilib_64_archs}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/adainclude
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/adalib
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/ada_target_properties
+%endif
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/ada_target_properties
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/gnat1
+%doc rpm.doc/changelogs/gcc/ada/ChangeLog*
+
+%files -n libgnat
+%{_prefix}/%{_lib}/libgnat-*.so
+%{_prefix}/%{_lib}/libgnarl-*.so
+
+%files -n libgnat-devel
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adainclude
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib
+%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib/libgnat.a
+%exclude %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib/libgnarl.a
+
+%files -n libgnat-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib/libgnat.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/adalib/libgnarl.a
+%endif
+
+%files -n libgomp
+%{_prefix}/%{_lib}/libgomp.so.1*
+%{_infodir}/libgomp.info*
+%doc rpm.doc/changelogs/libgomp/ChangeLog*
+
+%if %{build_libquadmath}
+%files -n libquadmath
+%{_prefix}/%{_lib}/libquadmath.so.0*
+%{_infodir}/libquadmath.info*
+%{!?_licensedir:%global license %%doc}
+%license rpm.doc/libquadmath/COPYING*
+
+%files -n libquadmath-devel
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/quadmath.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include/quadmath_weak.h
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libquadmath.so
+%doc rpm.doc/libquadmath/ChangeLog*
+
+%files -n libquadmath-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libquadmath.a
+%endif
+
+%if %{build_libitm}
+%files -n libitm
+%{_prefix}/%{_lib}/libitm.so.1*
+%{_infodir}/libitm.info*
+
+%files -n libitm-devel
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/include
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.so
+%doc rpm.doc/libitm/ChangeLog*
+
+%files -n libitm-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libitm.a
+%endif
+
+%if %{build_libatomic}
+%files -n libatomic
+%{_prefix}/%{_lib}/libatomic.so.1*
+
+%files -n libatomic-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libatomic.a
+%doc rpm.doc/changelogs/libatomic/ChangeLog*
+%endif
+
+%if %{build_libasan}
+%files -n libasan
+%{_prefix}/%{_lib}/libasan.so.8*
+
+%files -n libasan-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libasan.a
+%doc rpm.doc/changelogs/libsanitizer/ChangeLog*
+%{!?_licensedir:%global license %%doc}
+%license libsanitizer/LICENSE.TXT
+%endif
+
+%if %{build_libubsan}
+%files -n libubsan
+%{_prefix}/%{_lib}/libubsan.so.1*
+
+%files -n libubsan-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libubsan.a
+%doc rpm.doc/changelogs/libsanitizer/ChangeLog*
+%{!?_licensedir:%global license %%doc}
+%license libsanitizer/LICENSE.TXT
+%endif
+
+%if %{build_libtsan}
+%files -n libtsan
+%{_prefix}/%{_lib}/libtsan.so.2*
+
+%files -n libtsan-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libtsan.a
+%doc rpm.doc/changelogs/libsanitizer/ChangeLog*
+%{!?_licensedir:%global license %%doc}
+%license libsanitizer/LICENSE.TXT
+%endif
+
+%if %{build_liblsan}
+%files -n liblsan
+%{_prefix}/%{_lib}/liblsan.so.0*
+
+%files -n liblsan-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/liblsan.a
+%doc rpm.doc/changelogs/libsanitizer/ChangeLog*
+%{!?_licensedir:%global license %%doc}
+%license libsanitizer/LICENSE.TXT
+%endif
+
+%if %{build_go}
+%files go
+%ghost %{_prefix}/bin/go
+%attr(755,root,root) %{_prefix}/bin/go.gcc
+%{_prefix}/bin/gccgo
+%ghost %{_prefix}/bin/gofmt
+%attr(755,root,root) %{_prefix}/bin/gofmt.gcc
+%{_mandir}/man1/gccgo.1*
+%{_mandir}/man1/go.1*
+%{_mandir}/man1/gofmt.1*
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/go1
+%attr(755,root,root) %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/cgo
+%attr(755,root,root) %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/buildid
+%attr(755,root,root) %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/test2json
+%attr(755,root,root) %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/vet
+%ifarch %{multilib_64_archs}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgo.so
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgo.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgobegin.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/32/libgolibbegin.a
+%endif
+%ifarch %{multilib_64_archs}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgo.so
+%endif
+%doc rpm.doc/go/*
+
+%files -n libgo
+%attr(755,root,root) %{_prefix}/%{_lib}/libgo.so.21*
+%doc rpm.doc/libgo/*
+
+%files -n libgo-devel
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/%{_lib}/go
+%dir %{_prefix}/%{_lib}/go/%{gcc_major}
+%{_prefix}/%{_lib}/go/%{gcc_major}/%{gcc_target_platform}
+%ifarch %{multilib_64_archs}
+%dir %{_prefix}/lib/go
+%dir %{_prefix}/lib/go/%{gcc_major}
+%{_prefix}/lib/go/%{gcc_major}/%{gcc_target_platform}
+%endif
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgobegin.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgolibbegin.a
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgo.so
+
+%files -n libgo-static
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/libgo.a
+%endif
+
+%files -n libgccjit
+%{_prefix}/%{_lib}/libgccjit.so.*
+%doc rpm.doc/changelogs/gcc/jit/ChangeLog*
+
+%files -n libgccjit-devel
+%{_prefix}/%{_lib}/libgccjit.so
+%{_prefix}/include/libgccjit*.h
+%{_infodir}/libgccjit.info*
+%doc rpm.doc/libgccjit-devel/*
+%doc gcc/jit/docs/examples
+
+%files plugin-devel
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/gtype.state
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/include
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/plugin
+
+%files gdb-plugin
+%{_prefix}/%{_lib}/libcc1.so*
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/libcc1plugin.so*
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/plugin/libcp1plugin.so*
+%doc rpm.doc/changelogs/libcc1/ChangeLog*
+
+%if %{build_offload_nvptx}
+%files offload-nvptx
+%{_prefix}/bin/nvptx-none-*
+%{_prefix}/bin/%{gcc_target_platform}-accel-nvptx-none-gcc
+%{_prefix}/bin/%{gcc_target_platform}-accel-nvptx-none-lto-dump
+%dir %{_prefix}/lib/gcc
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/accel
+%dir %{_prefix}/libexec/gcc
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}
+%dir %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/accel
+%{_prefix}/lib/gcc/nvptx-none
+%{_prefix}/lib/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none
+%{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_major}/accel/nvptx-none
+%dir %{_prefix}/nvptx-none
+%{_prefix}/nvptx-none/bin
+%{_prefix}/nvptx-none/include
+
+%files -n libgomp-offload-nvptx
+%{_prefix}/%{_lib}/libgomp-plugin-nvptx.so.*
+%endif
+
+%changelog
+* Mon Feb 21 2022 Chunmei Xu - 12.0.1-0.8.1
+- upstream from gcc trunk, after gcc12 release, will transfer to gcc12 release
diff --git a/gcc12-Wno-format-security.patch b/gcc12-Wno-format-security.patch
new file mode 100644
index 0000000000000000000000000000000000000000..43e482a4e15cae2960bc502831b4645c4d72f8b7
--- /dev/null
+++ b/gcc12-Wno-format-security.patch
@@ -0,0 +1,58 @@
+2022-01-07 Jakub Jelinek
+
+ * Makefile.tpl (GOCFLAGS, GDCFLAGS): Filter out -Wformat-security.
+ * Makefile.in: Regenerated.
+
+2017-02-25 Jakub Jelinek
+
+ * configure.ac: When adding -Wno-format, also add -Wno-format-security.
+ * configure: Regenerated.
+
+--- gcc/configure.ac.jj 2017-02-13 12:20:53.000000000 +0100
++++ gcc/configure.ac 2017-02-25 12:42:32.859175403 +0100
+@@ -570,7 +570,7 @@ AC_ARG_ENABLE(build-format-warnings,
+ AS_HELP_STRING([--disable-build-format-warnings],[don't use -Wformat while building GCC]),
+ [],[enable_build_format_warnings=yes])
+ AS_IF([test $enable_build_format_warnings = no],
+- [wf_opt=-Wno-format],[wf_opt=])
++ [wf_opt="-Wno-format -Wno-format-security"],[wf_opt=])
+ ACX_PROG_CXX_WARNING_OPTS(
+ m4_quote(m4_do([-W -Wall -Wno-narrowing -Wwrite-strings ],
+ [-Wcast-qual $wf_opt])),
+--- gcc/configure.jj 2017-02-13 12:20:52.000000000 +0100
++++ gcc/configure 2017-02-25 12:42:50.041946391 +0100
+@@ -7077,7 +7077,7 @@ else
+ fi
+
+ if test $enable_build_format_warnings = no; then :
+- wf_opt=-Wno-format
++ wf_opt="-Wno-format -Wno-format-security"
+ else
+ wf_opt=
+ fi
+--- Makefile.tpl.jj 2021-12-30 15:12:42.188164847 +0100
++++ Makefile.tpl 2022-01-07 12:06:12.115550714 +0100
+@@ -447,8 +447,8 @@ LDFLAGS = @LDFLAGS@
+ LIBCFLAGS = $(CFLAGS)
+ CXXFLAGS = @CXXFLAGS@
+ LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates
+-GOCFLAGS = $(CFLAGS)
+-GDCFLAGS = $(CFLAGS)
++GOCFLAGS = $(filter-out -Wformat-security,$(CFLAGS))
++GDCFLAGS = $(filter-out -Wformat-security,$(CFLAGS))
+
+ # Pass additional PGO and LTO compiler options to the PGO build.
+ BUILD_CFLAGS = $(PGO_BUILD_CFLAGS) $(PGO_BUILD_LTO_CFLAGS)
+--- Makefile.in.jj 2021-12-30 15:12:42.188164847 +0100
++++ Makefile.in 2022-01-07 12:06:27.335334561 +0100
+@@ -444,8 +444,8 @@ LDFLAGS = @LDFLAGS@
+ LIBCFLAGS = $(CFLAGS)
+ CXXFLAGS = @CXXFLAGS@
+ LIBCXXFLAGS = $(CXXFLAGS) -fno-implicit-templates
+-GOCFLAGS = $(CFLAGS)
+-GDCFLAGS = $(CFLAGS)
++GOCFLAGS = $(filter-out -Wformat-security,$(CFLAGS))
++GDCFLAGS = $(filter-out -Wformat-security,$(CFLAGS))
+
+ # Pass additional PGO and LTO compiler options to the PGO build.
+ BUILD_CFLAGS = $(PGO_BUILD_CFLAGS) $(PGO_BUILD_LTO_CFLAGS)
diff --git a/gcc12-d-shared-libphobos.patch b/gcc12-d-shared-libphobos.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6384bbb556e68464fb55ee0fbabd5a478f73a037
--- /dev/null
+++ b/gcc12-d-shared-libphobos.patch
@@ -0,0 +1,20 @@
+2019-01-17 Jakub Jelinek
+
+ * d-spec.cc (lang_specific_driver): Make -shared-libphobos
+ the default rather than -static-libphobos.
+
+--- gcc/d/d-spec.cc.jj 2019-01-01 12:37:49.502444257 +0100
++++ gcc/d/d-spec.cc 2019-01-17 17:09:45.364949246 +0100
+@@ -408,9 +408,9 @@ lang_specific_driver (cl_decoded_option
+ /* Add `-lgphobos' if we haven't already done so. */
+ if (phobos_library != PHOBOS_NOLINK)
+ {
+- /* Default to static linking. */
+- if (phobos_library != PHOBOS_DYNAMIC)
+- phobos_library = PHOBOS_STATIC;
++ /* Default to shared linking. */
++ if (phobos_library != PHOBOS_STATIC)
++ phobos_library = PHOBOS_DYNAMIC;
+
+ #ifdef HAVE_LD_STATIC_DYNAMIC
+ if (phobos_library == PHOBOS_STATIC && !static_link)
diff --git a/gcc12-fortran-fdec-add-missing-indexes.patch b/gcc12-fortran-fdec-add-missing-indexes.patch
new file mode 100644
index 0000000000000000000000000000000000000000..529868f5f9678652f592885ae9c564a35f74f308
--- /dev/null
+++ b/gcc12-fortran-fdec-add-missing-indexes.patch
@@ -0,0 +1,181 @@
+From 7001d522d0273658d9e1fb12ca104d56bfcae34d Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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.cc | 1 +
+ gcc/fortran/resolve.cc | 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.cc b/gcc/fortran/options.cc
+index 050f56fdc25..c3b2822685d 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -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.cc b/gcc/fortran/resolve.cc
+index fe7d0cc5944..0efeedab46e 100644
+--- a/gcc/fortran/resolve.cc
++++ b/gcc/fortran/resolve.cc
+@@ -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
++! Updated by Mark Eggleston
++!
++
++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
++! Updated by Mark Eggleston
++!
++
++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
++! Updated by Mark Eggleston
++!
++
++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/gcc12-fortran-fdec-duplicates.patch b/gcc12-fortran-fdec-duplicates.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5298baa959a2336ea50a802cf4c80d09e82500af
--- /dev/null
+++ b/gcc12-fortran-fdec-duplicates.patch
@@ -0,0 +1,215 @@
+From 23b1fcb104c666429451ffaf936f8da5fcd3d43a Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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
+Addition of -fdec-duplicates by Mark Eggleston
+---
+ gcc/fortran/lang.opt | 4 ++++
+ gcc/fortran/options.cc | 1 +
+ gcc/fortran/symbol.cc | 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.cc b/gcc/fortran/options.cc
+index 3a0b98bf1ec..f19ba87f8a0 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -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.cc b/gcc/fortran/symbol.cc
+index 3b988d1be22..9843175cc2a 100644
+--- a/gcc/fortran/symbol.cc
++++ b/gcc/fortran/symbol.cc
+@@ -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
++!
++
++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
++!
++
++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
++!
++
++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
++!
++
++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
++!
++
++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/gcc12-fortran-fdec-ichar.patch b/gcc12-fortran-fdec-ichar.patch
new file mode 100644
index 0000000000000000000000000000000000000000..900b054ee1670d07d5fccdd68db3d0dd4d167acc
--- /dev/null
+++ b/gcc12-fortran-fdec-ichar.patch
@@ -0,0 +1,78 @@
+From f883ac209b0feea860354cb4ef7ff06dc8063fab Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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.cc | 2 +-
+ gcc/fortran/simplify.cc | 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.cc b/gcc/fortran/check.cc
+index 82db8e4e1b2..623c1cc470e 100644
+--- a/gcc/fortran/check.cc
++++ b/gcc/fortran/check.cc
+@@ -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.cc b/gcc/fortran/simplify.cc
+index 23317a2e2d9..9900572424f 100644
+--- a/gcc/fortran/simplify.cc
++++ b/gcc/fortran/simplify.cc
+@@ -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
++! Modified by Mark Eggleston
++!
++ 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/gcc12-fortran-fdec-non-integer-index.patch b/gcc12-fortran-fdec-non-integer-index.patch
new file mode 100644
index 0000000000000000000000000000000000000000..2c168fe926b3b61b680f55e65736e969fdf95217
--- /dev/null
+++ b/gcc12-fortran-fdec-non-integer-index.patch
@@ -0,0 +1,158 @@
+From 67aef262311d6a746786ee0f59748ccaa7e1e711 Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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.cc | 1 +
+ gcc/fortran/resolve.cc | 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.cc b/gcc/fortran/options.cc
+index f19ba87f8a0..9a042f64881 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -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.cc b/gcc/fortran/resolve.cc
+index 4b90cb59902..bc0df0fdb99 100644
+--- a/gcc/fortran/resolve.cc
++++ b/gcc/fortran/resolve.cc
+@@ -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
++!
++ 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
++!
++ 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
++!
++ 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/gcc12-fortran-fdec-non-logical-if.patch b/gcc12-fortran-fdec-non-logical-if.patch
new file mode 100644
index 0000000000000000000000000000000000000000..24a8fa492a0744678a2b2e8bf0b4835657a90e02
--- /dev/null
+++ b/gcc12-fortran-fdec-non-logical-if.patch
@@ -0,0 +1,378 @@
+From cc87ddb841017bb0976b05091733609ee17d7f05 Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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.cc | 1 +
+ gcc/fortran/resolve.cc | 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.cc b/gcc/fortran/options.cc
+index edbab483b36..a946c86790a 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -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.cc b/gcc/fortran/resolve.cc
+index bc0df0fdb99..07dd039f3bf 100644
+--- a/gcc/fortran/resolve.cc
++++ b/gcc/fortran/resolve.cc
+@@ -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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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/gcc12-fortran-fdec-old-init.patch b/gcc12-fortran-fdec-old-init.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d5661c870c84dbbc83bb41715f0accd5a78e3d45
--- /dev/null
+++ b/gcc12-fortran-fdec-old-init.patch
@@ -0,0 +1,185 @@
+From 8bcc0f85ed1718c0dd9033ad4a34df181aabaffe Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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.cc | 27 +++++++++++++++----
+ gcc/fortran/lang.opt | 4 +++
+ gcc/fortran/options.cc | 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.cc b/gcc/fortran/decl.cc
+index 723915822f3..5c8c1b7981b 100644
+--- a/gcc/fortran/decl.cc
++++ b/gcc/fortran/decl.cc
+@@ -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.cc b/gcc/fortran/options.cc
+index 9a042f64881..d6bd36c3a8a 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -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
++! Modified by Mark Eggleston
++!
++ 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
++! Modified by Mark Eggleston
++!
++ 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
++! Modified by Mark Eggleston
++!
++
++ 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/gcc12-fortran-fdec-override-kind.patch b/gcc12-fortran-fdec-override-kind.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4df6ead71a39e66b49c1883330a41d90dfdedff8
--- /dev/null
+++ b/gcc12-fortran-fdec-override-kind.patch
@@ -0,0 +1,588 @@
+From 786869fd62813e80da9b6545a295d53c36275c19 Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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
+
+Now rejects invalid kind parameters and prints error messages:
+
+ INTEGER X*3
+
+caused an internal compiler error.
+
+Contributed by Mark Eggleston
+---
+ gcc/fortran/decl.cc | 156 ++++++++++++++----
+ gcc/fortran/lang.opt | 4 +
+ gcc/fortran/options.cc | 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.cc b/gcc/fortran/decl.cc
+index 5c8c1b7981b..f7dc9d8263d 100644
+--- a/gcc/fortran/decl.cc
++++ b/gcc/fortran/decl.cc
+@@ -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.cc b/gcc/fortran/options.cc
+index d6bd36c3a8a..edbab483b36 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -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
++! Modified by Mark Eggleston
++!
++ 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
++! Modified by Mark Eggleston
++!
++ 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
++! Modified by Mark Eggleston
++!
++ 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
++!
++ 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
++!
++ 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
++!
++ 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
++!
++ 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
++!
++ 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
++!
++ 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
++!
++ 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
++!
++ 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/gcc12-fortran-fdec-promotion.patch b/gcc12-fortran-fdec-promotion.patch
new file mode 100644
index 0000000000000000000000000000000000000000..870d62a633bc222eb5c02ec5ad7e952b6307bc1e
--- /dev/null
+++ b/gcc12-fortran-fdec-promotion.patch
@@ -0,0 +1,2093 @@
+From 7a27318818e359a277f2fa5f7dc3932d0fb950f5 Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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 ,
+Francisco Redondo Marchena and
+Jeff Law
+
+Re-worked by Mark Eggleston
+---
+ gcc/fortran/check.cc | 71 +++++-
+ gcc/fortran/intrinsic.cc | 5 +
+ gcc/fortran/iresolve.cc | 91 ++++---
+ gcc/fortran/lang.opt | 4 +
+ gcc/fortran/options.cc | 1 +
+ gcc/fortran/simplify.cc | 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.cc b/gcc/fortran/check.cc
+index 623c1cc470e..e20a834a860 100644
+--- a/gcc/fortran/check.cc
++++ b/gcc/fortran/check.cc
+@@ -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 ("% 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.cc b/gcc/fortran/intrinsic.cc
+index e68eff8bdbb..81b3a24c2be 100644
+--- a/gcc/fortran/intrinsic.cc
++++ b/gcc/fortran/intrinsic.cc
+@@ -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.cc b/gcc/fortran/iresolve.cc
+index e17fe45f080..b9cdaff2499 100644
+--- a/gcc/fortran/iresolve.cc
++++ b/gcc/fortran/iresolve.cc
+@@ -834,19 +834,22 @@ gfc_resolve_dble (gfc_expr *f, gfc_expr
+ 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),
+@@ -1622,14 +1625,17 @@ gfc_resolve_minmax (const char *name, gf
+ /* 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);
+ }
+
+@@ -2130,19 +2136,22 @@ gfc_resolve_minval (gfc_expr *f, gfc_exp
+ 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),
+@@ -2153,19 +2162,22 @@ gfc_resolve_mod (gfc_expr *f, gfc_expr *
+ 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),
+@@ -2543,9 +2555,26 @@ gfc_resolve_shift (gfc_expr *f, gfc_expr
+
+
+ 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),
+ gfc_type_abi_kind (&a->ts));
+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.cc b/gcc/fortran/options.cc
+index a946c86790a..15079c7e95a 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -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.cc b/gcc/fortran/simplify.cc
+index 9900572424f..3419e06fec2 100644
+--- a/gcc/fortran/simplify.cc
++++ b/gcc/fortran/simplify.cc
+@@ -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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++! and Jeff Law
++! Modified by Mark Eggleston
++!
++ 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
++!
++ 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
++!
++ 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
++!
++ 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/gcc12-fortran-fdec-sequence.patch b/gcc12-fortran-fdec-sequence.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d79348e3cc4999dd2128184fa3b2f793d767ea91
--- /dev/null
+++ b/gcc12-fortran-fdec-sequence.patch
@@ -0,0 +1,262 @@
+From bb76446db10c21860a4e19569ce3e350d8a2b59f Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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.cc | 1 +
+ gcc/fortran/resolve.cc | 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.cc b/gcc/fortran/options.cc
+index 15079c7e95a..050f56fdc25 100644
+--- a/gcc/fortran/options.cc
++++ b/gcc/fortran/options.cc
+@@ -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.cc b/gcc/fortran/resolve.cc
+index 07dd039f3bf..fe7d0cc5944 100644
+--- a/gcc/fortran/resolve.cc
++++ b/gcc/fortran/resolve.cc
+@@ -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
++! Modified by Mark Eggleston
++!
++ 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
++! Modified by Mark Eggleston
++!
++ 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
++! Modified by Mark Eggleston
++!
++ 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/gcc12-fortran-flogical-as-integer.patch b/gcc12-fortran-flogical-as-integer.patch
new file mode 100644
index 0000000000000000000000000000000000000000..28df5e196d10eab40d78bdb189811eca22829286
--- /dev/null
+++ b/gcc12-fortran-flogical-as-integer.patch
@@ -0,0 +1,305 @@
+From 9b45f3063dfd2b893e7963a4828c1b0afecdc68a Mon Sep 17 00:00:00 2001
+From: Mark Eggleston
+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.cc | 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.cc b/gcc/fortran/resolve.cc
+index c075d0fa0c4..4b90cb59902 100644
+--- a/gcc/fortran/resolve.cc
++++ b/gcc/fortran/resolve.cc
+@@ -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
++! Modified for -flogical-as-integer by Mark Eggleston
++!
++!
++ 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
++!
++!
++ 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
+
diff --git a/gcc12-hack.patch b/gcc12-hack.patch
new file mode 100644
index 0000000000000000000000000000000000000000..e98649ef0aa596b11d25c7f6e2b3bbd92d183734
--- /dev/null
+++ b/gcc12-hack.patch
@@ -0,0 +1,126 @@
+--- libada/Makefile.in.jj 2019-01-09 13:01:18.015608205 +0100
++++ libada/Makefile.in 2019-01-11 18:16:23.441726931 +0100
+@@ -71,18 +71,40 @@ version := $(shell @get_gcc_base_ver@ $(
+ libsubdir := $(libdir)/gcc/$(target_noncanonical)/$(version)$(MULTISUBDIR)
+ ADA_RTS_DIR=$(GCC_DIR)/ada/rts$(subst /,_,$(MULTISUBDIR))
+
++DEFAULTMULTIFLAGS :=
++ifeq ($(MULTISUBDIR),)
++targ:=$(subst -, ,$(target))
++arch:=$(word 1,$(targ))
++ifeq ($(words $(targ)),2)
++osys:=$(word 2,$(targ))
++else
++osys:=$(word 3,$(targ))
++endif
++ifeq ($(strip $(filter-out i%86 x86_64 powerpc% ppc% s390% sparc% linux%, $(arch) $(osys))),)
++ifeq ($(shell $(CC) $(CFLAGS) -print-multi-os-directory),../lib64)
++DEFAULTMULTIFLAGS := -m64
++else
++ifeq ($(strip $(filter-out s390%, $(arch))),)
++DEFAULTMULTIFLAGS := -m31
++else
++DEFAULTMULTIFLAGS := -m32
++endif
++endif
++endif
++endif
++
+ # exeext should not be used because it's the *host* exeext. We're building
+ # a *target* library, aren't we?!? Likewise for CC. Still, provide bogus
+ # definitions just in case something slips through the safety net provided
+ # by recursive make invocations in gcc/ada/Makefile.in
+ LIBADA_FLAGS_TO_PASS = \
+ "MAKEOVERRIDES=" \
+- "LDFLAGS=$(LDFLAGS)" \
++ "LDFLAGS=$(LDFLAGS) $(DEFAULTMULTIFLAGS)" \
+ "LN_S=$(LN_S)" \
+ "SHELL=$(SHELL)" \
+- "GNATLIBFLAGS=$(GNATLIBFLAGS) $(MULTIFLAGS)" \
+- "GNATLIBCFLAGS=$(GNATLIBCFLAGS) $(MULTIFLAGS)" \
+- "GNATLIBCFLAGS_FOR_C=$(GNATLIBCFLAGS_FOR_C) $(MULTIFLAGS)" \
++ "GNATLIBFLAGS=$(GNATLIBFLAGS) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \
++ "GNATLIBCFLAGS=$(GNATLIBCFLAGS) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \
++ "GNATLIBCFLAGS_FOR_C=$(GNATLIBCFLAGS_FOR_C) $(MULTIFLAGS) $(DEFAULTMULTIFLAGS)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG)" \
+ "THREAD_KIND=$(THREAD_KIND)" \
+ "TRACE=$(TRACE)" \
+@@ -93,7 +115,7 @@ LIBADA_FLAGS_TO_PASS = \
+ "exeext=.exeext.should.not.be.used " \
+ 'CC=the.host.compiler.should.not.be.needed' \
+ "GCC_FOR_TARGET=$(CC)" \
+- "CFLAGS=$(CFLAGS)"
++ "CFLAGS=$(CFLAGS) $(DEFAULTMULTIFLAGS)"
+
+ .PHONY: libada gnatlib gnatlib-shared gnatlib-sjlj gnatlib-zcx osconstool
+
+--- config-ml.in.jj 2019-01-09 12:50:16.646501448 +0100
++++ config-ml.in 2019-01-11 18:16:23.442726914 +0100
+@@ -511,6 +511,8 @@ multi-do:
+ ADAFLAGS="$(ADAFLAGS) $${flags}" \
+ prefix="$(prefix)" \
+ exec_prefix="$(exec_prefix)" \
++ mandir="$(mandir)" \
++ infodir="$(infodir)" \
+ GOCFLAGS="$(GOCFLAGS) $${flags}" \
+ GDCFLAGS="$(GDCFLAGS) $${flags}" \
+ CXXFLAGS="$(CXXFLAGS) $${flags}" \
+--- libcpp/macro.cc.jj 2019-01-09 13:01:21.420552123 +0100
++++ libcpp/macro.cc 2019-01-11 18:18:17.736876285 +0100
+@@ -3256,8 +3256,6 @@ static cpp_macro *
+ create_iso_definition (cpp_reader *pfile)
+ {
+ bool following_paste_op = false;
+- const char *paste_op_error_msg =
+- N_("'##' cannot appear at either end of a macro expansion");
+ unsigned int num_extra_tokens = 0;
+ unsigned nparms = 0;
+ cpp_hashnode **params = NULL;
+@@ -3382,7 +3380,9 @@ create_iso_definition (cpp_reader *pfile
+ function-like macros, but not at the end. */
+ if (following_paste_op)
+ {
+- cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
++ cpp_error (pfile, CPP_DL_ERROR,
++ "'##' cannot appear at either end of a macro "
++ "expansion");
+ goto out;
+ }
+ if (!vaopt_tracker.completed ())
+@@ -3397,7 +3397,9 @@ create_iso_definition (cpp_reader *pfile
+ function-like macros, but not at the beginning. */
+ if (macro->count == 1)
+ {
+- cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
++ cpp_error (pfile, CPP_DL_ERROR,
++ "'##' cannot appear at either end of a macro "
++ "expansion");
+ goto out;
+ }
+
+--- libcpp/expr.cc.jj 2019-01-09 13:01:22.415535734 +0100
++++ libcpp/expr.cc 2019-01-11 18:16:23.444726882 +0100
+@@ -803,16 +803,17 @@ cpp_classify_number (cpp_reader *pfile,
+ if ((result & CPP_N_WIDTH) == CPP_N_LARGE
+ && CPP_OPTION (pfile, cpp_warn_long_long))
+ {
+- const char *message = CPP_OPTION (pfile, cplusplus)
+- ? N_("use of C++11 long long integer constant")
+- : N_("use of C99 long long integer constant");
+-
+ if (CPP_OPTION (pfile, c99))
+ cpp_warning_with_line (pfile, CPP_W_LONG_LONG, virtual_location,
+- 0, message);
++ 0, CPP_OPTION (pfile, cplusplus)
++ ? N_("use of C++11 long long integer constant")
++ : N_("use of C99 long long integer constant"));
+ else
+ cpp_pedwarning_with_line (pfile, CPP_W_LONG_LONG,
+- virtual_location, 0, message);
++ virtual_location, 0,
++ CPP_OPTION (pfile, cplusplus)
++ ? N_("use of C++11 long long integer constant")
++ : N_("use of C99 long long integer constant"));
+ }
+
+ if ((result & CPP_N_SIZE_T) == CPP_N_SIZE_T
diff --git a/gcc12-ifcvt-revert.patch b/gcc12-ifcvt-revert.patch
new file mode 100644
index 0000000000000000000000000000000000000000..dd13271724a36f4b00982546c0db8398e9f0d5a3
--- /dev/null
+++ b/gcc12-ifcvt-revert.patch
@@ -0,0 +1,1141 @@
+Revert r12-674{3,4,5,6,7,8,9} and r12-7114, as there are several PRs reported
+against those changes still unresolved.
+
+--- gcc/ifcvt.cc
++++ gcc/ifcvt.cc
+@@ -3391,11 +3391,7 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ rtx cond = noce_get_condition (jump, &cond_earliest, false);
+
+ rtx cc_cmp = cond_exec_get_condition (jump);
+- if (cc_cmp)
+- cc_cmp = copy_rtx (cc_cmp);
+ rtx rev_cc_cmp = cond_exec_get_condition (jump, /* get_reversed */ true);
+- if (rev_cc_cmp)
+- rev_cc_cmp = copy_rtx (rev_cc_cmp);
+
+ rtx_insn *insn;
+ int count = 0;
+@@ -3519,7 +3515,6 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ unsigned cost1 = 0, cost2 = 0;
+ rtx_insn *seq, *seq1, *seq2;
+ rtx temp_dest = NULL_RTX, temp_dest1 = NULL_RTX, temp_dest2 = NULL_RTX;
+- bool read_comparison = false;
+
+ seq1 = try_emit_cmove_seq (if_info, temp, cond,
+ new_val, old_val, need_cmov,
+@@ -3529,41 +3524,10 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ as well. This allows the backend to emit a cmov directly without
+ creating an additional compare for each. If successful, costing
+ is easier and this sequence is usually preferred. */
+- seq2 = try_emit_cmove_seq (if_info, temp, cond,
++ seq2 = try_emit_cmove_seq (if_info, target, cond,
+ new_val, old_val, need_cmov,
+ &cost2, &temp_dest2, cc_cmp, rev_cc_cmp);
+
+- /* The backend might have created a sequence that uses the
+- condition. Check this. */
+- rtx_insn *walk = seq2;
+- while (walk)
+- {
+- rtx set = single_set (walk);
+-
+- if (!set || !SET_SRC (set))
+- {
+- walk = NEXT_INSN (walk);
+- continue;
+- }
+-
+- rtx src = SET_SRC (set);
+-
+- if (XEXP (set, 1) && GET_CODE (XEXP (set, 1)) == IF_THEN_ELSE)
+- ; /* We assume that this is the cmove created by the backend that
+- naturally uses the condition. Therefore we ignore it. */
+- else
+- {
+- if (reg_mentioned_p (XEXP (cond, 0), src)
+- || reg_mentioned_p (XEXP (cond, 1), src))
+- {
+- read_comparison = true;
+- break;
+- }
+- }
+-
+- walk = NEXT_INSN (walk);
+- }
+-
+ /* Check which version is less expensive. */
+ if (seq1 != NULL_RTX && (cost1 <= cost2 || seq2 == NULL_RTX))
+ {
+@@ -3576,8 +3540,6 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ {
+ seq = seq2;
+ temp_dest = temp_dest2;
+- if (!second_try && read_comparison)
+- *last_needs_comparison = count;
+ }
+ else
+ {
+@@ -3596,12 +3558,6 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ unmodified_insns->safe_push (insn);
+ }
+
+- /* Even if we did not actually need the comparison, we want to make sure
+- to try a second time in order to get rid of the temporaries. */
+- if (*last_needs_comparison == -1)
+- *last_needs_comparison = 0;
+-
+-
+ return true;
+ }
+
+--- gcc/config/rs6000/rs6000.cc
++++ gcc/config/rs6000/rs6000.cc
+@@ -16373,10 +16373,10 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
+ c = GEU;
+
+ if (code == SMAX || code == UMAX)
+- target = emit_conditional_move (dest, { c, op0, op1, mode },
++ target = emit_conditional_move (dest, c, op0, op1, mode,
+ op0, op1, mode, 0);
+ else
+- target = emit_conditional_move (dest, { c, op0, op1, mode },
++ target = emit_conditional_move (dest, c, op0, op1, mode,
+ op1, op0, mode, 0);
+ gcc_assert (target);
+ if (target != dest)
+@@ -22769,7 +22769,7 @@ rs6000_emit_swsqrt (rtx dst, rtx src, bool recip)
+
+ if (mode == SFmode)
+ {
+- rtx target = emit_conditional_move (e, { GT, src, zero, mode },
++ rtx target = emit_conditional_move (e, GT, src, zero, mode,
+ e, zero, mode, 0);
+ if (target != e)
+ emit_move_insn (e, target);
+--- gcc/expmed.cc
++++ gcc/expmed.cc
+@@ -4124,8 +4124,8 @@ expand_sdiv_pow2 (scalar_int_mode mode, rtx op0, HOST_WIDE_INT d)
+ temp = force_reg (mode, temp);
+
+ /* Construct "temp2 = (temp2 < 0) ? temp : temp2". */
+- temp2 = emit_conditional_move (temp2, { LT, temp2, const0_rtx, mode },
+- temp, temp2, mode, 0);
++ temp2 = emit_conditional_move (temp2, LT, temp2, const0_rtx,
++ mode, temp, temp2, mode, 0);
+ if (temp2)
+ {
+ rtx_insn *seq = get_insns ();
+@@ -6127,10 +6127,10 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
+ return 0;
+
+ if (and_them)
+- tem = emit_conditional_move (target, { code, op0, op1, mode },
++ tem = emit_conditional_move (target, code, op0, op1, mode,
+ tem, const0_rtx, GET_MODE (tem), 0);
+ else
+- tem = emit_conditional_move (target, { code, op0, op1, mode },
++ tem = emit_conditional_move (target, code, op0, op1, mode,
+ trueval, tem, GET_MODE (tem), 0);
+
+ if (tem == 0)
+--- gcc/expr.cc
++++ gcc/expr.cc
+@@ -8824,9 +8824,8 @@ expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED,
+ op2 = gen_lowpart (mode, op2);
+
+ /* Try to emit the conditional move. */
+- insn = emit_conditional_move (temp,
+- { comparison_code, op00, op01,
+- comparison_mode },
++ insn = emit_conditional_move (temp, comparison_code,
++ op00, op01, comparison_mode,
+ op1, op2, mode,
+ unsignedp);
+
+@@ -9717,9 +9716,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
+ start_sequence ();
+
+ /* Try to emit the conditional move. */
+- insn = emit_conditional_move (target,
+- { comparison_code,
+- op0, cmpop1, mode },
++ insn = emit_conditional_move (target, comparison_code,
++ op0, cmpop1, mode,
+ op0, op1, mode,
+ unsignedp);
+
+--- gcc/ifcvt.cc
++++ gcc/ifcvt.cc
+@@ -83,7 +83,7 @@ static rtx_insn *last_active_insn (basic_block, int);
+ static rtx_insn *find_active_insn_before (basic_block, rtx_insn *);
+ static rtx_insn *find_active_insn_after (basic_block, rtx_insn *);
+ static basic_block block_fallthru (basic_block);
+-static rtx cond_exec_get_condition (rtx_insn *, bool);
++static rtx cond_exec_get_condition (rtx_insn *);
+ static rtx noce_get_condition (rtx_insn *, rtx_insn **, bool);
+ static int noce_operand_ok (const_rtx);
+ static void merge_if_block (ce_if_block *);
+@@ -98,14 +98,6 @@ static int dead_or_predicable (basic_block, basic_block, basic_block,
+ edge, int);
+ static void noce_emit_move_insn (rtx, rtx);
+ static rtx_insn *block_has_only_trap (basic_block);
+-static void need_cmov_or_rewire (basic_block, hash_set *,
+- hash_map *);
+-static bool noce_convert_multiple_sets_1 (struct noce_if_info *,
+- hash_set *,
+- hash_map *,
+- auto_vec *,
+- auto_vec *,
+- auto_vec *, int *);
+
+ /* Count the number of non-jump active insns in BB. */
+
+@@ -433,7 +425,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED,
+ /* Return the condition for a jump. Do not do any special processing. */
+
+ static rtx
+-cond_exec_get_condition (rtx_insn *jump, bool get_reversed = false)
++cond_exec_get_condition (rtx_insn *jump)
+ {
+ rtx test_if, cond;
+
+@@ -445,10 +437,8 @@ cond_exec_get_condition (rtx_insn *jump, bool get_reversed = false)
+
+ /* If this branches to JUMP_LABEL when the condition is false,
+ reverse the condition. */
+- if (get_reversed
+- || (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
+- && label_ref_label (XEXP (test_if, 2))
+- == JUMP_LABEL (jump)))
++ if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
++ && label_ref_label (XEXP (test_if, 2)) == JUMP_LABEL (jump))
+ {
+ enum rtx_code rev = reversed_comparison_code (cond, jump);
+ if (rev == UNKNOWN)
+@@ -780,7 +770,7 @@ static int noce_try_addcc (struct noce_if_info *);
+ static int noce_try_store_flag_constants (struct noce_if_info *);
+ static int noce_try_store_flag_mask (struct noce_if_info *);
+ static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
+- rtx, rtx, rtx, rtx = NULL, rtx = NULL);
++ rtx, rtx, rtx);
+ static int noce_try_cmove (struct noce_if_info *);
+ static int noce_try_cmove_arith (struct noce_if_info *);
+ static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **);
+@@ -1719,8 +1709,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
+
+ static rtx
+ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
+- rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue, rtx cc_cmp,
+- rtx rev_cc_cmp)
++ rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
+ {
+ rtx target ATTRIBUTE_UNUSED;
+ int unsignedp ATTRIBUTE_UNUSED;
+@@ -1752,30 +1741,23 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
+ end_sequence ();
+ }
+
+- unsignedp = (code == LTU || code == GEU
+- || code == LEU || code == GTU);
+-
+- if (cc_cmp != NULL_RTX && rev_cc_cmp != NULL_RTX)
+- target = emit_conditional_move (x, cc_cmp, rev_cc_cmp,
+- vtrue, vfalse, GET_MODE (x));
+- else
++ /* Don't even try if the comparison operands are weird
++ except that the target supports cbranchcc4. */
++ if (! general_operand (cmp_a, GET_MODE (cmp_a))
++ || ! general_operand (cmp_b, GET_MODE (cmp_b)))
+ {
+- /* Don't even try if the comparison operands are weird
+- except that the target supports cbranchcc4. */
+- if (! general_operand (cmp_a, GET_MODE (cmp_a))
+- || ! general_operand (cmp_b, GET_MODE (cmp_b)))
+- {
+- if (!have_cbranchcc4
+- || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
+- || cmp_b != const0_rtx)
+- return NULL_RTX;
+- }
+-
+- target = emit_conditional_move (x, { code, cmp_a, cmp_b, VOIDmode },
+- vtrue, vfalse, GET_MODE (x),
+- unsignedp);
++ if (!have_cbranchcc4
++ || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
++ || cmp_b != const0_rtx)
++ return NULL_RTX;
+ }
+
++ unsignedp = (code == LTU || code == GEU
++ || code == LEU || code == GTU);
++
++ target = emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
++ vtrue, vfalse, GET_MODE (x),
++ unsignedp);
+ if (target)
+ return target;
+
+@@ -1811,9 +1793,8 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
+
+ promoted_target = gen_reg_rtx (GET_MODE (reg_vtrue));
+
+- target = emit_conditional_move (promoted_target,
+- { code, cmp_a, cmp_b, VOIDmode },
+- reg_vtrue, reg_vfalse,
++ target = emit_conditional_move (promoted_target, code, cmp_a, cmp_b,
++ VOIDmode, reg_vtrue, reg_vfalse,
+ GET_MODE (reg_vtrue), unsignedp);
+ /* Nope, couldn't do it in that mode either. */
+ if (!target)
+@@ -3160,50 +3141,6 @@ bb_valid_for_noce_process_p (basic_block test_bb, rtx cond,
+ return false;
+ }
+
+-/* Helper function to emit a cmov sequence encapsulated in
+- start_sequence () and end_sequence (). If NEED_CMOV is true
+- we call noce_emit_cmove to create a cmove sequence. Otherwise emit
+- a simple move. If successful, store the first instruction of the
+- sequence in TEMP_DEST and the sequence costs in SEQ_COST. */
+-
+-static rtx_insn*
+-try_emit_cmove_seq (struct noce_if_info *if_info, rtx temp,
+- rtx cond, rtx new_val, rtx old_val, bool need_cmov,
+- unsigned *cost, rtx *temp_dest,
+- rtx cc_cmp = NULL, rtx rev_cc_cmp = NULL)
+-{
+- rtx_insn *seq = NULL;
+- *cost = 0;
+-
+- rtx x = XEXP (cond, 0);
+- rtx y = XEXP (cond, 1);
+- rtx_code cond_code = GET_CODE (cond);
+-
+- start_sequence ();
+-
+- if (need_cmov)
+- *temp_dest = noce_emit_cmove (if_info, temp, cond_code,
+- x, y, new_val, old_val, cc_cmp, rev_cc_cmp);
+- else
+- {
+- *temp_dest = temp;
+- if (if_info->then_else_reversed)
+- noce_emit_move_insn (temp, old_val);
+- else
+- noce_emit_move_insn (temp, new_val);
+- }
+-
+- if (*temp_dest != NULL_RTX)
+- {
+- seq = get_insns ();
+- *cost = seq_cost (seq, if_info->speed_p);
+- }
+-
+- end_sequence ();
+-
+- return seq;
+-}
+-
+ /* We have something like:
+
+ if (x > y)
+@@ -3261,6 +3198,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
+ rtx cond = noce_get_condition (jump, &cond_earliest, false);
+ rtx x = XEXP (cond, 0);
+ rtx y = XEXP (cond, 1);
++ rtx_code cond_code = GET_CODE (cond);
+
+ /* The true targets for a conditional move. */
+ auto_vec targets;
+@@ -3269,139 +3207,8 @@ noce_convert_multiple_sets (struct noce_if_info *if_info)
+ auto_vec temporaries;
+ /* The insns we've emitted. */
+ auto_vec unmodified_insns;
+-
+- hash_set need_no_cmov;
+- hash_map rewired_src;
+-
+- need_cmov_or_rewire (then_bb, &need_no_cmov, &rewired_src);
+-
+- int last_needs_comparison = -1;
+-
+- bool ok = noce_convert_multiple_sets_1
+- (if_info, &need_no_cmov, &rewired_src, &targets, &temporaries,
+- &unmodified_insns, &last_needs_comparison);
+- if (!ok)
+- return false;
+-
+- /* If there are insns that overwrite part of the initial
+- comparison, we can still omit creating temporaries for
+- the last of them.
+- As the second try will always create a less expensive,
+- valid sequence, we do not need to compare and can discard
+- the first one. */
+- if (last_needs_comparison != -1)
+- {
+- end_sequence ();
+- start_sequence ();
+- ok = noce_convert_multiple_sets_1
+- (if_info, &need_no_cmov, &rewired_src, &targets, &temporaries,
+- &unmodified_insns, &last_needs_comparison);
+- /* Actually we should not fail anymore if we reached here,
+- but better still check. */
+- if (!ok)
+- return false;
+- }
+-
+- /* We must have seen some sort of insn to insert, otherwise we were
+- given an empty BB to convert, and we can't handle that. */
+- gcc_assert (!unmodified_insns.is_empty ());
+-
+- /* Now fixup the assignments. */
+- for (unsigned i = 0; i < targets.length (); i++)
+- if (targets[i] != temporaries[i])
+- noce_emit_move_insn (targets[i], temporaries[i]);
+-
+- /* Actually emit the sequence if it isn't too expensive. */
+- rtx_insn *seq = get_insns ();
+-
+- if (!targetm.noce_conversion_profitable_p (seq, if_info))
+- {
+- end_sequence ();
+- return FALSE;
+- }
+-
+- for (insn = seq; insn; insn = NEXT_INSN (insn))
+- set_used_flags (insn);
+-
+- /* Mark all our temporaries and targets as used. */
+- for (unsigned i = 0; i < targets.length (); i++)
+- {
+- set_used_flags (temporaries[i]);
+- set_used_flags (targets[i]);
+- }
+-
+- set_used_flags (cond);
+- set_used_flags (x);
+- set_used_flags (y);
+-
+- unshare_all_rtl_in_chain (seq);
+- end_sequence ();
+-
+- if (!seq)
+- return FALSE;
+-
+- for (insn = seq; insn; insn = NEXT_INSN (insn))
+- if (JUMP_P (insn)
+- || recog_memoized (insn) == -1)
+- return FALSE;
+-
+- emit_insn_before_setloc (seq, if_info->jump,
+- INSN_LOCATION (unmodified_insns.last ()));
+-
+- /* Clean up THEN_BB and the edges in and out of it. */
+- remove_edge (find_edge (test_bb, join_bb));
+- remove_edge (find_edge (then_bb, join_bb));
+- redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb);
+- delete_basic_block (then_bb);
+- num_true_changes++;
+-
+- /* Maybe merge blocks now the jump is simple enough. */
+- if (can_merge_blocks_p (test_bb, join_bb))
+- {
+- merge_blocks (test_bb, join_bb);
+- num_true_changes++;
+- }
+-
+- num_updated_if_blocks++;
+- if_info->transform_name = "noce_convert_multiple_sets";
+- return TRUE;
+-}
+-
+-/* This goes through all relevant insns of IF_INFO->then_bb and tries to
+- create conditional moves. In case a simple move sufficis the insn
+- should be listed in NEED_NO_CMOV. The rewired-src cases should be
+- specified via REWIRED_SRC. TARGETS, TEMPORARIES and UNMODIFIED_INSNS
+- are specified and used in noce_convert_multiple_sets and should be passed
+- to this function.. */
+-
+-static bool
+-noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+- hash_set *need_no_cmov,
+- hash_map *rewired_src,
+- auto_vec *targets,
+- auto_vec *temporaries,
+- auto_vec *unmodified_insns,
+- int *last_needs_comparison)
+-{
+- basic_block then_bb = if_info->then_bb;
+- rtx_insn *jump = if_info->jump;
+- rtx_insn *cond_earliest;
+-
+- /* Decompose the condition attached to the jump. */
+- rtx cond = noce_get_condition (jump, &cond_earliest, false);
+-
+- rtx cc_cmp = cond_exec_get_condition (jump);
+- rtx rev_cc_cmp = cond_exec_get_condition (jump, /* get_reversed */ true);
+-
+- rtx_insn *insn;
+ int count = 0;
+
+- targets->truncate (0);
+- temporaries->truncate (0);
+- unmodified_insns->truncate (0);
+-
+- bool second_try = *last_needs_comparison != -1;
+-
+ FOR_BB_INSNS (then_bb, insn)
+ {
+ /* Skip over non-insns. */
+@@ -3412,53 +3219,26 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ gcc_checking_assert (set);
+
+ rtx target = SET_DEST (set);
+- rtx temp;
+-
++ rtx temp = gen_reg_rtx (GET_MODE (target));
+ rtx new_val = SET_SRC (set);
+- if (int *ii = rewired_src->get (insn))
+- new_val = simplify_replace_rtx (new_val, (*targets)[*ii],
+- (*temporaries)[*ii]);
+ rtx old_val = target;
+
+- /* As we are transforming
+- if (x > y)
+- {
+- a = b;
+- c = d;
+- }
+- into
+- a = (x > y) ...
+- c = (x > y) ...
+-
+- we potentially check x > y before every set.
+- Even though the check might be removed by subsequent passes, this means
+- that we cannot transform
+- if (x > y)
+- {
+- x = y;
+- ...
+- }
+- into
+- x = (x > y) ...
+- ...
+- since this would invalidate x and the following to-be-removed checks.
+- Therefore we introduce a temporary every time we are about to
+- overwrite a variable used in the check. Costing of a sequence with
+- these is going to be inaccurate so only use temporaries when
+- needed.
+-
+- If performing a second try, we know how many insns require a
+- temporary. For the last of these, we can omit creating one. */
+- if (reg_overlap_mentioned_p (target, cond)
+- && (!second_try || count < *last_needs_comparison))
+- temp = gen_reg_rtx (GET_MODE (target));
+- else
+- temp = target;
+-
+- /* We have identified swap-style idioms before. A normal
+- set will need to be a cmov while the first instruction of a swap-style
+- idiom can be a regular move. This helps with costing. */
+- bool need_cmov = !need_no_cmov->contains (insn);
++ /* If we were supposed to read from an earlier write in this block,
++ we've changed the register allocation. Rewire the read. While
++ we are looking, also try to catch a swap idiom. */
++ for (int i = count - 1; i >= 0; --i)
++ if (reg_overlap_mentioned_p (new_val, targets[i]))
++ {
++ /* Catch a "swap" style idiom. */
++ if (find_reg_note (insn, REG_DEAD, new_val) != NULL_RTX)
++ /* The write to targets[i] is only live until the read
++ here. As the condition codes match, we can propagate
++ the set to here. */
++ new_val = SET_SRC (single_set (unmodified_insns[i]));
++ else
++ new_val = temporaries[i];
++ break;
++ }
+
+ /* If we had a non-canonical conditional jump (i.e. one where
+ the fallthrough is to the "else" case) we need to reverse
+@@ -3478,9 +3258,7 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ we'll end up trying to emit r4:HI = cond ? (r1:SI) : (r3:HI).
+ Wrap the two cmove operands into subregs if appropriate to prevent
+ that. */
+-
+- if (!CONSTANT_P (new_val)
+- && GET_MODE (new_val) != GET_MODE (temp))
++ if (GET_MODE (new_val) != GET_MODE (temp))
+ {
+ machine_mode src_mode = GET_MODE (new_val);
+ machine_mode dst_mode = GET_MODE (temp);
+@@ -3491,8 +3269,7 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ }
+ new_val = lowpart_subreg (dst_mode, new_val, src_mode);
+ }
+- if (!CONSTANT_P (old_val)
+- && GET_MODE (old_val) != GET_MODE (temp))
++ if (GET_MODE (old_val) != GET_MODE (temp))
+ {
+ machine_mode src_mode = GET_MODE (old_val);
+ machine_mode dst_mode = GET_MODE (temp);
+@@ -3504,80 +3281,101 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
+ old_val = lowpart_subreg (dst_mode, old_val, src_mode);
+ }
+
+- /* Try emitting a conditional move passing the backend the
+- canonicalized comparison. The backend is then able to
+- recognize expressions like
+-
+- if (x > y)
+- y = x;
+-
+- as min/max and emit an insn, accordingly. */
+- unsigned cost1 = 0, cost2 = 0;
+- rtx_insn *seq, *seq1, *seq2;
+- rtx temp_dest = NULL_RTX, temp_dest1 = NULL_RTX, temp_dest2 = NULL_RTX;
++ /* Actually emit the conditional move. */
++ rtx temp_dest = noce_emit_cmove (if_info, temp, cond_code,
++ x, y, new_val, old_val);
+
+- seq1 = try_emit_cmove_seq (if_info, temp, cond,
+- new_val, old_val, need_cmov,
+- &cost1, &temp_dest1);
+-
+- /* Here, we try to pass the backend a non-canonicalized cc comparison
+- as well. This allows the backend to emit a cmov directly without
+- creating an additional compare for each. If successful, costing
+- is easier and this sequence is usually preferred. */
+- seq2 = try_emit_cmove_seq (if_info, target, cond,
+- new_val, old_val, need_cmov,
+- &cost2, &temp_dest2, cc_cmp, rev_cc_cmp);
+-
+- /* Check which version is less expensive. */
+- if (seq1 != NULL_RTX && (cost1 <= cost2 || seq2 == NULL_RTX))
+- {
+- seq = seq1;
+- temp_dest = temp_dest1;
+- if (!second_try)
+- *last_needs_comparison = count;
+- }
+- else if (seq2 != NULL_RTX)
+- {
+- seq = seq2;
+- temp_dest = temp_dest2;
+- }
+- else
++ /* If we failed to expand the conditional move, drop out and don't
++ try to continue. */
++ if (temp_dest == NULL_RTX)
+ {
+- /* Nothing worked, bail out. */
+ end_sequence ();
+ return FALSE;
+ }
+
+- /* End the sub sequence and emit to the main sequence. */
+- emit_insn (seq);
+-
+ /* Bookkeeping. */
+ count++;
+- targets->safe_push (target);
+- temporaries->safe_push (temp_dest);
+- unmodified_insns->safe_push (insn);
++ targets.safe_push (target);
++ temporaries.safe_push (temp_dest);
++ unmodified_insns.safe_push (insn);
+ }
+
+- return true;
+-}
++ /* We must have seen some sort of insn to insert, otherwise we were
++ given an empty BB to convert, and we can't handle that. */
++ gcc_assert (!unmodified_insns.is_empty ());
++
++ /* Now fixup the assignments. */
++ for (int i = 0; i < count; i++)
++ noce_emit_move_insn (targets[i], temporaries[i]);
++
++ /* Actually emit the sequence if it isn't too expensive. */
++ rtx_insn *seq = get_insns ();
++
++ if (!targetm.noce_conversion_profitable_p (seq, if_info))
++ {
++ end_sequence ();
++ return FALSE;
++ }
++
++ for (insn = seq; insn; insn = NEXT_INSN (insn))
++ set_used_flags (insn);
++
++ /* Mark all our temporaries and targets as used. */
++ for (int i = 0; i < count; i++)
++ {
++ set_used_flags (temporaries[i]);
++ set_used_flags (targets[i]);
++ }
+
++ set_used_flags (cond);
++ set_used_flags (x);
++ set_used_flags (y);
+
++ unshare_all_rtl_in_chain (seq);
++ end_sequence ();
++
++ if (!seq)
++ return FALSE;
++
++ for (insn = seq; insn; insn = NEXT_INSN (insn))
++ if (JUMP_P (insn)
++ || recog_memoized (insn) == -1)
++ return FALSE;
++
++ emit_insn_before_setloc (seq, if_info->jump,
++ INSN_LOCATION (unmodified_insns.last ()));
++
++ /* Clean up THEN_BB and the edges in and out of it. */
++ remove_edge (find_edge (test_bb, join_bb));
++ remove_edge (find_edge (then_bb, join_bb));
++ redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb);
++ delete_basic_block (then_bb);
++ num_true_changes++;
++
++ /* Maybe merge blocks now the jump is simple enough. */
++ if (can_merge_blocks_p (test_bb, join_bb))
++ {
++ merge_blocks (test_bb, join_bb);
++ num_true_changes++;
++ }
++
++ num_updated_if_blocks++;
++ if_info->transform_name = "noce_convert_multiple_sets";
++ return TRUE;
++}
+
+ /* Return true iff basic block TEST_BB is comprised of only
+ (SET (REG) (REG)) insns suitable for conversion to a series
+ of conditional moves. Also check that we have more than one set
+ (other routines can handle a single set better than we would), and
+- fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. While going
+- through the insns store the sum of their potential costs in COST. */
++ fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. */
+
+ static bool
+-bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost)
++bb_ok_for_noce_convert_multiple_sets (basic_block test_bb)
+ {
+ rtx_insn *insn;
+ unsigned count = 0;
+ unsigned param = param_max_rtl_if_conversion_insns;
+- bool speed_p = optimize_bb_for_speed_p (test_bb);
+- unsigned potential_cost = 0;
+
+ FOR_BB_INSNS (test_bb, insn)
+ {
+@@ -3600,9 +3398,9 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost)
+ if (!REG_P (dest))
+ return false;
+
+- if (!((REG_P (src) || CONSTANT_P (src))
+- || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
+- && subreg_lowpart_p (src))))
++ if (!(REG_P (src)
++ || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
++ && subreg_lowpart_p (src))))
+ return false;
+
+ /* Destination must be appropriate for a conditional write. */
+@@ -3613,13 +3411,9 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost)
+ if (!can_conditionally_move_p (GET_MODE (dest)))
+ return false;
+
+- potential_cost += insn_cost (insn, speed_p);
+-
+ count++;
+ }
+
+- *cost += potential_cost;
+-
+ /* If we would only put out one conditional move, the other strategies
+ this pass tries are better optimized and will be more appropriate.
+ Some targets want to strictly limit the number of conditional moves
+@@ -3667,24 +3461,11 @@ noce_process_if_block (struct noce_if_info *if_info)
+ to calculate a value for x.
+ ??? For future expansion, further expand the "multiple X" rules. */
+
+- /* First look for multiple SETS. The original costs already include
+- a base cost of COSTS_N_INSNS (2): one instruction for the compare
+- (which we will be needing either way) and one instruction for the
+- branch. When comparing costs we want to use the branch instruction
+- cost and the sets vs. the cmovs generated here. Therefore subtract
+- the costs of the compare before checking.
+- ??? Actually, instead of the branch instruction costs we might want
+- to use COSTS_N_INSNS (BRANCH_COST ()) as in other places. */
+-
+- unsigned potential_cost = if_info->original_cost - COSTS_N_INSNS (1);
+- unsigned old_cost = if_info->original_cost;
++ /* First look for multiple SETS. */
+ if (!else_bb
+ && HAVE_conditional_move
+- && bb_ok_for_noce_convert_multiple_sets (then_bb, &potential_cost))
++ && bb_ok_for_noce_convert_multiple_sets (then_bb))
+ {
+- /* Temporarily set the original costs to what we estimated so
+- we can determine if the transformation is worth it. */
+- if_info->original_cost = potential_cost;
+ if (noce_convert_multiple_sets (if_info))
+ {
+ if (dump_file && if_info->transform_name)
+@@ -3692,9 +3473,6 @@ noce_process_if_block (struct noce_if_info *if_info)
+ if_info->transform_name);
+ return TRUE;
+ }
+-
+- /* Restore the original costs. */
+- if_info->original_cost = old_cost;
+ }
+
+ bool speed_p = optimize_bb_for_speed_p (test_bb);
+@@ -4036,89 +3814,6 @@ check_cond_move_block (basic_block bb,
+ return TRUE;
+ }
+
+-/* Find local swap-style idioms in BB and mark the first insn (1)
+- that is only a temporary as not needing a conditional move as
+- it is going to be dead afterwards anyway.
+-
+- (1) int tmp = a;
+- a = b;
+- b = tmp;
+-
+- ifcvt
+- -->
+-
+- tmp = a;
+- a = cond ? b : a_old;
+- b = cond ? tmp : b_old;
+-
+- Additionally, store the index of insns like (2) when a subsequent
+- SET reads from their destination.
+-
+- (2) int c = a;
+- int d = c;
+-
+- ifcvt
+- -->
+-
+- c = cond ? a : c_old;
+- d = cond ? d : c; // Need to use c rather than c_old here.
+-*/
+-
+-static void
+-need_cmov_or_rewire (basic_block bb,
+- hash_set *need_no_cmov,
+- hash_map *rewired_src)
+-{
+- rtx_insn *insn;
+- int count = 0;
+- auto_vec insns;
+- auto_vec dests;
+-
+- /* Iterate over all SETs, storing the destinations
+- in DEST.
+- - If we hit a SET that reads from a destination
+- that we have seen before and the corresponding register
+- is dead afterwards, the register does not need to be
+- moved conditionally.
+- - If we encounter a previously changed register,
+- rewire the read to the original source. */
+- FOR_BB_INSNS (bb, insn)
+- {
+- rtx set, src, dest;
+-
+- if (!active_insn_p (insn))
+- continue;
+-
+- set = single_set (insn);
+- if (set == NULL_RTX)
+- continue;
+-
+- src = SET_SRC (set);
+- if (SUBREG_P (src))
+- src = SUBREG_REG (src);
+- dest = SET_DEST (set);
+-
+- /* Check if the current SET's source is the same
+- as any previously seen destination.
+- This is quadratic but the number of insns in BB
+- is bounded by PARAM_MAX_RTL_IF_CONVERSION_INSNS. */
+- if (REG_P (src))
+- for (int i = count - 1; i >= 0; --i)
+- if (reg_overlap_mentioned_p (src, dests[i]))
+- {
+- if (find_reg_note (insn, REG_DEAD, src) != NULL_RTX)
+- need_no_cmov->add (insns[i]);
+- else
+- rewired_src->put (insn, i);
+- }
+-
+- insns.safe_push (insn);
+- dests.safe_push (dest);
+-
+- count++;
+- }
+-}
+-
+ /* Given a basic block BB suitable for conditional move conversion,
+ a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing
+ the register values depending on COND, emit the insns in the block as
+--- gcc/optabs.cc
++++ gcc/optabs.cc
+@@ -52,8 +52,6 @@ static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
+ static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
+ static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
+
+-static rtx emit_conditional_move_1 (rtx, rtx, rtx, rtx, machine_mode);
+-
+ /* Debug facility for use in GDB. */
+ void debug_optab_libfuncs (void);
+
+@@ -626,13 +624,12 @@ expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab,
+
+ /* Select between them. Do the INTO half first because INTO_SUPERWORD
+ might be the current value of OUTOF_TARGET. */
+- if (!emit_conditional_move (into_target, { cmp_code, cmp1, cmp2, op1_mode },
++ if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
+ into_target, into_superword, word_mode, false))
+ return false;
+
+ if (outof_target != 0)
+- if (!emit_conditional_move (outof_target,
+- { cmp_code, cmp1, cmp2, op1_mode },
++ if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
+ outof_target, outof_superword,
+ word_mode, false))
+ return false;
+@@ -4854,8 +4851,8 @@ emit_indirect_jump (rtx loc)
+ is not supported. */
+
+ rtx
+-emit_conditional_move (rtx target, struct rtx_comparison comp,
+- rtx op2, rtx op3,
++emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
++ machine_mode cmode, rtx op2, rtx op3,
+ machine_mode mode, int unsignedp)
+ {
+ rtx comparison;
+@@ -4877,33 +4874,31 @@ emit_conditional_move (rtx target, struct rtx_comparison comp,
+ /* If one operand is constant, make it the second one. Only do this
+ if the other operand is not constant as well. */
+
+- if (swap_commutative_operands_p (comp.op0, comp.op1))
++ if (swap_commutative_operands_p (op0, op1))
+ {
+- std::swap (comp.op0, comp.op1);
+- comp.code = swap_condition (comp.code);
++ std::swap (op0, op1);
++ code = swap_condition (code);
+ }
+
+ /* get_condition will prefer to generate LT and GT even if the old
+ comparison was against zero, so undo that canonicalization here since
+ comparisons against zero are cheaper. */
++ if (code == LT && op1 == const1_rtx)
++ code = LE, op1 = const0_rtx;
++ else if (code == GT && op1 == constm1_rtx)
++ code = GE, op1 = const0_rtx;
+
+- if (comp.code == LT && comp.op1 == const1_rtx)
+- comp.code = LE, comp.op1 = const0_rtx;
+- else if (comp.code == GT && comp.op1 == constm1_rtx)
+- comp.code = GE, comp.op1 = const0_rtx;
+-
+- if (comp.mode == VOIDmode)
+- comp.mode = GET_MODE (comp.op0);
++ if (cmode == VOIDmode)
++ cmode = GET_MODE (op0);
+
+- enum rtx_code orig_code = comp.code;
++ enum rtx_code orig_code = code;
+ bool swapped = false;
+ if (swap_commutative_operands_p (op2, op3)
+- && ((reversed =
+- reversed_comparison_code_parts (comp.code, comp.op0, comp.op1, NULL))
+- != UNKNOWN))
++ && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
++ != UNKNOWN))
+ {
+ std::swap (op2, op3);
+- comp.code = reversed;
++ code = reversed;
+ swapped = true;
+ }
+
+@@ -4920,10 +4915,8 @@ emit_conditional_move (rtx target, struct rtx_comparison comp,
+
+ for (int pass = 0; ; pass++)
+ {
+- comp.code = unsignedp ? unsigned_condition (comp.code) : comp.code;
+- comparison =
+- simplify_gen_relational (comp.code, VOIDmode,
+- comp.mode, comp.op0, comp.op1);
++ code = unsignedp ? unsigned_condition (code) : code;
++ comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
+
+ /* We can get const0_rtx or const_true_rtx in some circumstances. Just
+ punt and let the caller figure out how best to deal with this
+@@ -4934,16 +4927,24 @@ emit_conditional_move (rtx target, struct rtx_comparison comp,
+ save_pending_stack_adjust (&save);
+ last = get_last_insn ();
+ do_pending_stack_adjust ();
+- machine_mode cmpmode = comp.mode;
++ machine_mode cmpmode = cmode;
+ prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
+ GET_CODE (comparison), NULL_RTX, unsignedp,
+ OPTAB_WIDEN, &comparison, &cmpmode);
+ if (comparison)
+ {
+- rtx res = emit_conditional_move_1 (target, comparison,
+- op2, op3, mode);
+- if (res != NULL_RTX)
+- return res;
++ class expand_operand ops[4];
++
++ create_output_operand (&ops[0], target, mode);
++ create_fixed_operand (&ops[1], comparison);
++ create_input_operand (&ops[2], op2, mode);
++ create_input_operand (&ops[3], op3, mode);
++ if (maybe_expand_insn (icode, 4, ops))
++ {
++ if (ops[0].value != target)
++ convert_move (target, ops[0].value, false);
++ return target;
++ }
+ }
+ delete_insns_since (last);
+ restore_pending_stack_adjust (&save);
+@@ -4955,88 +4956,17 @@ emit_conditional_move (rtx target, struct rtx_comparison comp,
+ /* If the preferred op2/op3 order is not usable, retry with other
+ operand order, perhaps it will expand successfully. */
+ if (swapped)
+- comp.code = orig_code;
+- else if ((reversed =
+- reversed_comparison_code_parts (orig_code, comp.op0, comp.op1,
++ code = orig_code;
++ else if ((reversed = reversed_comparison_code_parts (orig_code, op0, op1,
+ NULL))
+ != UNKNOWN)
+- comp.code = reversed;
++ code = reversed;
+ else
+ return NULL_RTX;
+ std::swap (op2, op3);
+ }
+ }
+
+-/* Helper function that, in addition to COMPARISON, also tries
+- the reversed REV_COMPARISON with swapped OP2 and OP3. As opposed
+- to when we pass the specific constituents of a comparison, no
+- additional insns are emitted for it. It might still be necessary
+- to emit more than one insn for the final conditional move, though. */
+-
+-rtx
+-emit_conditional_move (rtx target, rtx comparison, rtx rev_comparison,
+- rtx op2, rtx op3, machine_mode mode)
+-{
+- rtx res = emit_conditional_move_1 (target, comparison, op2, op3, mode);
+-
+- if (res != NULL_RTX)
+- return res;
+-
+- return emit_conditional_move_1 (target, rev_comparison, op3, op2, mode);
+-}
+-
+-/* Helper for emitting a conditional move. */
+-
+-static rtx
+-emit_conditional_move_1 (rtx target, rtx comparison,
+- rtx op2, rtx op3, machine_mode mode)
+-{
+- enum insn_code icode;
+-
+- if (comparison == NULL_RTX || !COMPARISON_P (comparison))
+- return NULL_RTX;
+-
+- /* If the two source operands are identical, that's just a move.
+- As the comparison comes in non-canonicalized, we must make
+- sure not to discard any possible side effects. If there are
+- side effects, just let the target handle it. */
+- if (!side_effects_p (comparison) && rtx_equal_p (op2, op3))
+- {
+- if (!target)
+- target = gen_reg_rtx (mode);
+-
+- emit_move_insn (target, op3);
+- return target;
+- }
+-
+- if (mode == VOIDmode)
+- mode = GET_MODE (op2);
+-
+- icode = direct_optab_handler (movcc_optab, mode);
+-
+- if (icode == CODE_FOR_nothing)
+- return NULL_RTX;
+-
+- if (!target)
+- target = gen_reg_rtx (mode);
+-
+- class expand_operand ops[4];
+-
+- create_output_operand (&ops[0], target, mode);
+- create_fixed_operand (&ops[1], comparison);
+- create_input_operand (&ops[2], op2, mode);
+- create_input_operand (&ops[3], op3, mode);
+-
+- if (maybe_expand_insn (icode, 4, ops))
+- {
+- if (ops[0].value != target)
+- convert_move (target, ops[0].value, false);
+- return target;
+- }
+-
+- return NULL_RTX;
+-}
+-
+
+ /* Emit a conditional negate or bitwise complement using the
+ negcc or notcc optabs if available. Return NULL_RTX if such operations
+--- gcc/optabs.h
++++ gcc/optabs.h
+@@ -279,8 +279,8 @@ extern void emit_indirect_jump (rtx);
+ #endif
+
+ /* Emit a conditional move operation. */
+-rtx emit_conditional_move (rtx, rtx_comparison, rtx, rtx, machine_mode, int);
+-rtx emit_conditional_move (rtx, rtx, rtx, rtx, rtx, machine_mode);
++rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, machine_mode,
++ rtx, rtx, machine_mode, int);
+
+ /* Emit a conditional negate or bitwise complement operation. */
+ rtx emit_conditional_neg_or_complement (rtx, rtx_code, machine_mode, rtx,
+--- gcc/rtl.h
++++ gcc/rtl.h
+@@ -4604,16 +4604,7 @@ word_register_operation_p (const_rtx x)
+ return true;
+ }
+ }
+-
+-/* Holds an rtx comparison to simplify passing many parameters pertaining to a
+- single comparison. */
+-
+-struct rtx_comparison {
+- rtx_code code;
+- rtx op0, op1;
+- machine_mode mode;
+-};
+-
++
+ /* gtype-desc.cc. */
+ extern void gt_ggc_mx (rtx &);
+ extern void gt_pch_nx (rtx &);
diff --git a/gcc12-isl-dl.patch b/gcc12-isl-dl.patch
new file mode 100644
index 0000000000000000000000000000000000000000..825fb88c54b4623ca299f5e3969d64e92916ae0f
--- /dev/null
+++ b/gcc12-isl-dl.patch
@@ -0,0 +1,716 @@
+--- gcc/Makefile.in.jj 2015-06-06 10:00:25.000000000 +0200
++++ gcc/Makefile.in 2015-11-04 14:56:02.643536437 +0100
+@@ -1063,7 +1063,7 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
+ # and the system's installed libraries.
+ LIBS = @LIBS@ libcommon.a $(CPPLIB) $(LIBINTL) $(LIBICONV) $(LIBBACKTRACE) \
+ $(LIBIBERTY) $(LIBDECNUMBER) $(HOST_LIBS)
+-BACKENDLIBS = $(ISLLIBS) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \
++BACKENDLIBS = $(if $(ISLLIBS),-ldl) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \
+ $(ZLIB) $(ZSTD_LIB)
+ # Any system libraries needed just for GNAT.
+ SYSLIBS = @GNAT_LIBEXC@
+@@ -2302,6 +2302,15 @@ $(out_object_file): $(out_file)
+ $(common_out_object_file): $(common_out_file)
+ $(COMPILE) $<
+ $(POSTCOMPILE)
++
++graphite%.o : \
++ ALL_CFLAGS := -O $(filter-out -fkeep-inline-functions, $(ALL_CFLAGS))
++graphite.o : \
++ ALL_CFLAGS := -O $(filter-out -fkeep-inline-functions, $(ALL_CFLAGS))
++graphite%.o : \
++ ALL_CXXFLAGS := -O $(filter-out -fkeep-inline-functions, $(ALL_CXXFLAGS))
++graphite.o : \
++ ALL_CXXFLAGS := -O $(filter-out -fkeep-inline-functions, $(ALL_CXXFLAGS))
+ #
+ # Generate header and source files from the machine description,
+ # and compile them.
+--- gcc/graphite.h.jj 2016-01-27 12:44:06.000000000 +0100
++++ gcc/graphite.h 2016-01-27 13:26:38.309876856 +0100
+@@ -24,6 +24,591 @@ along with GCC; see the file COPYING3.
+
+ #include "sese.h"
+
++#include
++#include
++
++#define DYNSYMS \
++ DYNSYM (isl_aff_add_coefficient_si); \
++ DYNSYM (isl_aff_free); \
++ DYNSYM (isl_aff_get_space); \
++ DYNSYM (isl_aff_set_coefficient_si); \
++ DYNSYM (isl_aff_set_constant_si); \
++ DYNSYM (isl_aff_zero_on_domain); \
++ DYNSYM (isl_band_free); \
++ DYNSYM (isl_band_get_children); \
++ DYNSYM (isl_band_get_partial_schedule); \
++ DYNSYM (isl_band_has_children); \
++ DYNSYM (isl_band_list_free); \
++ DYNSYM (isl_band_list_get_band); \
++ DYNSYM (isl_band_list_get_ctx); \
++ DYNSYM (isl_band_list_n_band); \
++ DYNSYM (isl_band_n_member); \
++ DYNSYM (isl_basic_map_add_constraint); \
++ DYNSYM (isl_basic_map_project_out); \
++ DYNSYM (isl_basic_map_universe); \
++ DYNSYM (isl_constraint_set_coefficient_si); \
++ DYNSYM (isl_constraint_set_constant_si); \
++ DYNSYM (isl_ctx_alloc); \
++ DYNSYM (isl_ctx_free); \
++ DYNSYM (isl_equality_alloc); \
++ DYNSYM (isl_id_alloc); \
++ DYNSYM (isl_id_copy); \
++ DYNSYM (isl_id_free); \
++ DYNSYM (isl_inequality_alloc); \
++ DYNSYM (isl_local_space_copy); \
++ DYNSYM (isl_local_space_free); \
++ DYNSYM (isl_local_space_from_space); \
++ DYNSYM (isl_local_space_range); \
++ DYNSYM (isl_map_add_constraint); \
++ DYNSYM (isl_map_add_dims); \
++ DYNSYM (isl_map_align_params); \
++ DYNSYM (isl_map_apply_range); \
++ DYNSYM (isl_map_copy); \
++ DYNSYM (isl_map_dim); \
++ DYNSYM (isl_map_dump); \
++ DYNSYM (isl_map_equate); \
++ DYNSYM (isl_map_fix_si); \
++ DYNSYM (isl_map_flat_product); \
++ DYNSYM (isl_map_flat_range_product); \
++ DYNSYM (isl_map_free); \
++ DYNSYM (isl_map_from_basic_map); \
++ DYNSYM (isl_map_from_pw_aff); \
++ DYNSYM (isl_map_from_union_map); \
++ DYNSYM (isl_map_get_ctx); \
++ DYNSYM (isl_map_get_space); \
++ DYNSYM (isl_map_get_tuple_id); \
++ DYNSYM (isl_map_insert_dims); \
++ DYNSYM (isl_map_intersect); \
++ DYNSYM (isl_map_intersect_domain); \
++ DYNSYM (isl_map_intersect_range); \
++ DYNSYM (isl_map_is_empty); \
++ DYNSYM (isl_map_lex_ge); \
++ DYNSYM (isl_map_lex_le); \
++ DYNSYM (isl_map_n_out); \
++ DYNSYM (isl_map_range); \
++ DYNSYM (isl_map_set_tuple_id); \
++ DYNSYM (isl_map_universe); \
++ DYNSYM (isl_options_set_on_error); \
++ DYNSYM (isl_options_set_schedule_serialize_sccs); \
++ DYNSYM (isl_printer_set_yaml_style); \
++ DYNSYM (isl_options_set_schedule_max_constant_term); \
++ DYNSYM (isl_options_set_schedule_maximize_band_depth); \
++ DYNSYM (isl_printer_free); \
++ DYNSYM (isl_printer_print_aff); \
++ DYNSYM (isl_printer_print_constraint); \
++ DYNSYM (isl_printer_print_map); \
++ DYNSYM (isl_printer_print_set); \
++ DYNSYM (isl_printer_to_file); \
++ DYNSYM (isl_pw_aff_add); \
++ DYNSYM (isl_pw_aff_alloc); \
++ DYNSYM (isl_pw_aff_copy); \
++ DYNSYM (isl_pw_aff_eq_set); \
++ DYNSYM (isl_pw_aff_free); \
++ DYNSYM (isl_pw_aff_from_aff); \
++ DYNSYM (isl_pw_aff_ge_set); \
++ DYNSYM (isl_pw_aff_gt_set); \
++ DYNSYM (isl_pw_aff_is_cst); \
++ DYNSYM (isl_pw_aff_le_set); \
++ DYNSYM (isl_pw_aff_lt_set); \
++ DYNSYM (isl_pw_aff_mul); \
++ DYNSYM (isl_pw_aff_ne_set); \
++ DYNSYM (isl_pw_aff_nonneg_set); \
++ DYNSYM (isl_pw_aff_set_tuple_id); \
++ DYNSYM (isl_pw_aff_sub); \
++ DYNSYM (isl_pw_aff_zero_set); \
++ DYNSYM (isl_schedule_free); \
++ DYNSYM (isl_schedule_get_band_forest); \
++ DYNSYM (isl_set_add_constraint); \
++ DYNSYM (isl_set_add_dims); \
++ DYNSYM (isl_set_apply); \
++ DYNSYM (isl_set_coalesce); \
++ DYNSYM (isl_set_copy); \
++ DYNSYM (isl_set_dim); \
++ DYNSYM (isl_set_fix_si); \
++ DYNSYM (isl_set_free); \
++ DYNSYM (isl_set_get_space); \
++ DYNSYM (isl_set_get_tuple_id); \
++ DYNSYM (isl_set_intersect); \
++ DYNSYM (isl_set_is_empty); \
++ DYNSYM (isl_set_n_dim); \
++ DYNSYM (isl_set_nat_universe); \
++ DYNSYM (isl_set_project_out); \
++ DYNSYM (isl_set_set_tuple_id); \
++ DYNSYM (isl_set_universe); \
++ DYNSYM (isl_space_add_dims); \
++ DYNSYM (isl_space_alloc); \
++ DYNSYM (isl_space_copy); \
++ DYNSYM (isl_space_dim); \
++ DYNSYM (isl_space_domain); \
++ DYNSYM (isl_space_find_dim_by_id); \
++ DYNSYM (isl_space_free); \
++ DYNSYM (isl_space_from_domain); \
++ DYNSYM (isl_space_get_tuple_id); \
++ DYNSYM (isl_space_params_alloc); \
++ DYNSYM (isl_space_range); \
++ DYNSYM (isl_space_set_alloc); \
++ DYNSYM (isl_space_set_dim_id); \
++ DYNSYM (isl_space_set_tuple_id); \
++ DYNSYM (isl_union_map_add_map); \
++ DYNSYM (isl_union_map_align_params); \
++ DYNSYM (isl_union_map_apply_domain); \
++ DYNSYM (isl_union_map_apply_range); \
++ DYNSYM (isl_union_map_compute_flow); \
++ DYNSYM (isl_union_map_copy); \
++ DYNSYM (isl_union_map_empty); \
++ DYNSYM (isl_union_map_flat_range_product); \
++ DYNSYM (isl_union_map_foreach_map); \
++ DYNSYM (isl_union_map_free); \
++ DYNSYM (isl_union_map_from_map); \
++ DYNSYM (isl_union_map_get_ctx); \
++ DYNSYM (isl_union_map_get_space); \
++ DYNSYM (isl_union_map_gist_domain); \
++ DYNSYM (isl_union_map_gist_range); \
++ DYNSYM (isl_union_map_intersect_domain); \
++ DYNSYM (isl_union_map_is_empty); \
++ DYNSYM (isl_union_map_subtract); \
++ DYNSYM (isl_union_map_union); \
++ DYNSYM (isl_union_set_add_set); \
++ DYNSYM (isl_union_set_compute_schedule); \
++ DYNSYM (isl_union_set_copy); \
++ DYNSYM (isl_union_set_empty); \
++ DYNSYM (isl_union_set_from_set); \
++ DYNSYM (isl_aff_add_constant_val); \
++ DYNSYM (isl_aff_get_coefficient_val); \
++ DYNSYM (isl_aff_get_ctx); \
++ DYNSYM (isl_aff_mod_val); \
++ DYNSYM (isl_ast_build_ast_from_schedule); \
++ DYNSYM (isl_ast_build_free); \
++ DYNSYM (isl_ast_build_from_context); \
++ DYNSYM (isl_ast_build_get_ctx); \
++ DYNSYM (isl_ast_build_get_schedule); \
++ DYNSYM (isl_ast_build_get_schedule_space); \
++ DYNSYM (isl_ast_build_set_before_each_for); \
++ DYNSYM (isl_ast_build_set_options); \
++ DYNSYM (isl_ast_expr_free); \
++ DYNSYM (isl_ast_expr_from_val); \
++ DYNSYM (isl_ast_expr_get_ctx); \
++ DYNSYM (isl_ast_expr_get_id); \
++ DYNSYM (isl_ast_expr_get_op_arg); \
++ DYNSYM (isl_ast_expr_get_op_n_arg); \
++ DYNSYM (isl_ast_expr_get_op_type); \
++ DYNSYM (isl_ast_expr_get_type); \
++ DYNSYM (isl_ast_expr_get_val); \
++ DYNSYM (isl_ast_expr_sub); \
++ DYNSYM (isl_ast_node_block_get_children); \
++ DYNSYM (isl_ast_node_for_get_body); \
++ DYNSYM (isl_ast_node_for_get_cond); \
++ DYNSYM (isl_ast_node_for_get_inc); \
++ DYNSYM (isl_ast_node_for_get_init); \
++ DYNSYM (isl_ast_node_for_get_iterator); \
++ DYNSYM (isl_ast_node_free); \
++ DYNSYM (isl_ast_node_get_annotation); \
++ DYNSYM (isl_ast_node_get_type); \
++ DYNSYM (isl_ast_node_if_get_cond); \
++ DYNSYM (isl_ast_node_if_get_else); \
++ DYNSYM (isl_ast_node_if_get_then); \
++ DYNSYM (isl_ast_node_list_free); \
++ DYNSYM (isl_ast_node_list_get_ast_node); \
++ DYNSYM (isl_ast_node_list_n_ast_node); \
++ DYNSYM (isl_ast_node_user_get_expr); \
++ DYNSYM (isl_constraint_set_coefficient_val); \
++ DYNSYM (isl_constraint_set_constant_val); \
++ DYNSYM (isl_id_get_user); \
++ DYNSYM (isl_local_space_get_ctx); \
++ DYNSYM (isl_map_fix_val); \
++ DYNSYM (isl_options_set_ast_build_atomic_upper_bound); \
++ DYNSYM (isl_printer_print_ast_node); \
++ DYNSYM (isl_printer_print_str); \
++ DYNSYM (isl_printer_set_output_format); \
++ DYNSYM (isl_pw_aff_mod_val); \
++ DYNSYM (isl_schedule_constraints_compute_schedule); \
++ DYNSYM (isl_schedule_constraints_on_domain); \
++ DYNSYM (isl_schedule_constraints_set_coincidence); \
++ DYNSYM (isl_schedule_constraints_set_proximity); \
++ DYNSYM (isl_schedule_constraints_set_validity); \
++ DYNSYM (isl_set_get_dim_id); \
++ DYNSYM (isl_set_max_val); \
++ DYNSYM (isl_set_min_val); \
++ DYNSYM (isl_set_params); \
++ DYNSYM (isl_space_align_params); \
++ DYNSYM (isl_space_map_from_domain_and_range); \
++ DYNSYM (isl_space_set_tuple_name); \
++ DYNSYM (isl_space_wrap); \
++ DYNSYM (isl_union_map_from_domain_and_range); \
++ DYNSYM (isl_union_map_range); \
++ DYNSYM (isl_union_set_union); \
++ DYNSYM (isl_union_set_universe); \
++ DYNSYM (isl_val_2exp); \
++ DYNSYM (isl_val_add_ui); \
++ DYNSYM (isl_val_copy); \
++ DYNSYM (isl_val_free); \
++ DYNSYM (isl_val_int_from_si); \
++ DYNSYM (isl_val_int_from_ui); \
++ DYNSYM (isl_val_mul); \
++ DYNSYM (isl_val_neg); \
++ DYNSYM (isl_val_sub); \
++ DYNSYM (isl_printer_print_union_map); \
++ DYNSYM (isl_pw_aff_get_ctx); \
++ DYNSYM (isl_val_is_int); \
++ DYNSYM (isl_ctx_get_max_operations); \
++ DYNSYM (isl_ctx_set_max_operations); \
++ DYNSYM (isl_ctx_last_error); \
++ DYNSYM (isl_ctx_reset_operations); \
++ DYNSYM (isl_map_coalesce); \
++ DYNSYM (isl_printer_print_schedule); \
++ DYNSYM (isl_set_set_dim_id); \
++ DYNSYM (isl_union_map_coalesce); \
++ DYNSYM (isl_multi_val_set_val); \
++ DYNSYM (isl_multi_val_zero); \
++ DYNSYM (isl_options_set_schedule_max_coefficient); \
++ DYNSYM (isl_options_set_tile_scale_tile_loops); \
++ DYNSYM (isl_schedule_copy); \
++ DYNSYM (isl_schedule_get_map); \
++ DYNSYM (isl_schedule_map_schedule_node_bottom_up); \
++ DYNSYM (isl_schedule_node_band_get_permutable); \
++ DYNSYM (isl_schedule_node_band_get_space); \
++ DYNSYM (isl_schedule_node_band_tile); \
++ DYNSYM (isl_schedule_node_child); \
++ DYNSYM (isl_schedule_node_free); \
++ DYNSYM (isl_schedule_node_get_child); \
++ DYNSYM (isl_schedule_node_get_ctx); \
++ DYNSYM (isl_schedule_node_get_type); \
++ DYNSYM (isl_schedule_node_n_children); \
++ DYNSYM (isl_union_map_is_equal); \
++ DYNSYM (isl_union_access_info_compute_flow); \
++ DYNSYM (isl_union_access_info_from_sink); \
++ DYNSYM (isl_union_access_info_set_may_source); \
++ DYNSYM (isl_union_access_info_set_must_source); \
++ DYNSYM (isl_union_access_info_set_schedule); \
++ DYNSYM (isl_union_flow_free); \
++ DYNSYM (isl_union_flow_get_may_dependence); \
++ DYNSYM (isl_union_flow_get_must_dependence); \
++ DYNSYM (isl_aff_var_on_domain); \
++ DYNSYM (isl_multi_aff_from_aff); \
++ DYNSYM (isl_schedule_get_ctx); \
++ DYNSYM (isl_multi_aff_set_tuple_id); \
++ DYNSYM (isl_multi_aff_dim); \
++ DYNSYM (isl_schedule_get_domain); \
++ DYNSYM (isl_union_set_is_empty); \
++ DYNSYM (isl_union_set_get_space); \
++ DYNSYM (isl_union_pw_multi_aff_empty); \
++ DYNSYM (isl_union_set_foreach_set); \
++ DYNSYM (isl_union_set_free); \
++ DYNSYM (isl_multi_union_pw_aff_from_union_pw_multi_aff); \
++ DYNSYM (isl_multi_union_pw_aff_apply_multi_aff); \
++ DYNSYM (isl_schedule_insert_partial_schedule); \
++ DYNSYM (isl_union_pw_multi_aff_free); \
++ DYNSYM (isl_pw_multi_aff_project_out_map); \
++ DYNSYM (isl_union_pw_multi_aff_add_pw_multi_aff); \
++ DYNSYM (isl_schedule_from_domain); \
++ DYNSYM (isl_schedule_sequence); \
++ DYNSYM (isl_ast_build_node_from_schedule); \
++ DYNSYM (isl_ast_node_mark_get_node); \
++ DYNSYM (isl_schedule_node_band_member_get_ast_loop_type); \
++ DYNSYM (isl_schedule_node_band_member_set_ast_loop_type); \
++ DYNSYM (isl_val_n_abs_num_chunks); \
++ DYNSYM (isl_val_get_abs_num_chunks); \
++ DYNSYM (isl_val_int_from_chunks); \
++ DYNSYM (isl_val_is_neg); \
++ DYNSYM (isl_version); \
++ DYNSYM (isl_options_get_on_error); \
++ DYNSYM (isl_ctx_reset_error);
++
++extern struct isl_pointers_s__
++{
++ bool inited;
++ void *h;
++#define DYNSYM(x) __typeof (x) *p_##x
++ DYNSYMS
++#undef DYNSYM
++} isl_pointers__;
++
++#define isl_aff_add_coefficient_si (*isl_pointers__.p_isl_aff_add_coefficient_si)
++#define isl_aff_free (*isl_pointers__.p_isl_aff_free)
++#define isl_aff_get_space (*isl_pointers__.p_isl_aff_get_space)
++#define isl_aff_set_coefficient_si (*isl_pointers__.p_isl_aff_set_coefficient_si)
++#define isl_aff_set_constant_si (*isl_pointers__.p_isl_aff_set_constant_si)
++#define isl_aff_zero_on_domain (*isl_pointers__.p_isl_aff_zero_on_domain)
++#define isl_band_free (*isl_pointers__.p_isl_band_free)
++#define isl_band_get_children (*isl_pointers__.p_isl_band_get_children)
++#define isl_band_get_partial_schedule (*isl_pointers__.p_isl_band_get_partial_schedule)
++#define isl_band_has_children (*isl_pointers__.p_isl_band_has_children)
++#define isl_band_list_free (*isl_pointers__.p_isl_band_list_free)
++#define isl_band_list_get_band (*isl_pointers__.p_isl_band_list_get_band)
++#define isl_band_list_get_ctx (*isl_pointers__.p_isl_band_list_get_ctx)
++#define isl_band_list_n_band (*isl_pointers__.p_isl_band_list_n_band)
++#define isl_band_n_member (*isl_pointers__.p_isl_band_n_member)
++#define isl_basic_map_add_constraint (*isl_pointers__.p_isl_basic_map_add_constraint)
++#define isl_basic_map_project_out (*isl_pointers__.p_isl_basic_map_project_out)
++#define isl_basic_map_universe (*isl_pointers__.p_isl_basic_map_universe)
++#define isl_constraint_set_coefficient_si (*isl_pointers__.p_isl_constraint_set_coefficient_si)
++#define isl_constraint_set_constant_si (*isl_pointers__.p_isl_constraint_set_constant_si)
++#define isl_ctx_alloc (*isl_pointers__.p_isl_ctx_alloc)
++#define isl_ctx_free (*isl_pointers__.p_isl_ctx_free)
++#define isl_equality_alloc (*isl_pointers__.p_isl_equality_alloc)
++#define isl_id_alloc (*isl_pointers__.p_isl_id_alloc)
++#define isl_id_copy (*isl_pointers__.p_isl_id_copy)
++#define isl_id_free (*isl_pointers__.p_isl_id_free)
++#define isl_inequality_alloc (*isl_pointers__.p_isl_inequality_alloc)
++#define isl_local_space_copy (*isl_pointers__.p_isl_local_space_copy)
++#define isl_local_space_free (*isl_pointers__.p_isl_local_space_free)
++#define isl_local_space_from_space (*isl_pointers__.p_isl_local_space_from_space)
++#define isl_local_space_range (*isl_pointers__.p_isl_local_space_range)
++#define isl_map_add_constraint (*isl_pointers__.p_isl_map_add_constraint)
++#define isl_map_add_dims (*isl_pointers__.p_isl_map_add_dims)
++#define isl_map_align_params (*isl_pointers__.p_isl_map_align_params)
++#define isl_map_apply_range (*isl_pointers__.p_isl_map_apply_range)
++#define isl_map_copy (*isl_pointers__.p_isl_map_copy)
++#define isl_map_dim (*isl_pointers__.p_isl_map_dim)
++#define isl_map_dump (*isl_pointers__.p_isl_map_dump)
++#define isl_map_equate (*isl_pointers__.p_isl_map_equate)
++#define isl_map_fix_si (*isl_pointers__.p_isl_map_fix_si)
++#define isl_map_flat_product (*isl_pointers__.p_isl_map_flat_product)
++#define isl_map_flat_range_product (*isl_pointers__.p_isl_map_flat_range_product)
++#define isl_map_free (*isl_pointers__.p_isl_map_free)
++#define isl_map_from_basic_map (*isl_pointers__.p_isl_map_from_basic_map)
++#define isl_map_from_pw_aff (*isl_pointers__.p_isl_map_from_pw_aff)
++#define isl_map_from_union_map (*isl_pointers__.p_isl_map_from_union_map)
++#define isl_map_get_ctx (*isl_pointers__.p_isl_map_get_ctx)
++#define isl_map_get_space (*isl_pointers__.p_isl_map_get_space)
++#define isl_map_get_tuple_id (*isl_pointers__.p_isl_map_get_tuple_id)
++#define isl_map_insert_dims (*isl_pointers__.p_isl_map_insert_dims)
++#define isl_map_intersect (*isl_pointers__.p_isl_map_intersect)
++#define isl_map_intersect_domain (*isl_pointers__.p_isl_map_intersect_domain)
++#define isl_map_intersect_range (*isl_pointers__.p_isl_map_intersect_range)
++#define isl_map_is_empty (*isl_pointers__.p_isl_map_is_empty)
++#define isl_map_lex_ge (*isl_pointers__.p_isl_map_lex_ge)
++#define isl_map_lex_le (*isl_pointers__.p_isl_map_lex_le)
++#define isl_map_n_out (*isl_pointers__.p_isl_map_n_out)
++#define isl_map_range (*isl_pointers__.p_isl_map_range)
++#define isl_map_set_tuple_id (*isl_pointers__.p_isl_map_set_tuple_id)
++#define isl_map_universe (*isl_pointers__.p_isl_map_universe)
++#define isl_options_set_on_error (*isl_pointers__.p_isl_options_set_on_error)
++#define isl_options_set_schedule_serialize_sccs (*isl_pointers__.p_isl_options_set_schedule_serialize_sccs)
++#define isl_printer_set_yaml_style (*isl_pointers__.p_isl_printer_set_yaml_style)
++#define isl_options_set_schedule_max_constant_term (*isl_pointers__.p_isl_options_set_schedule_max_constant_term)
++#define isl_options_set_schedule_maximize_band_depth (*isl_pointers__.p_isl_options_set_schedule_maximize_band_depth)
++#define isl_printer_free (*isl_pointers__.p_isl_printer_free)
++#define isl_printer_print_aff (*isl_pointers__.p_isl_printer_print_aff)
++#define isl_printer_print_constraint (*isl_pointers__.p_isl_printer_print_constraint)
++#define isl_printer_print_map (*isl_pointers__.p_isl_printer_print_map)
++#define isl_printer_print_set (*isl_pointers__.p_isl_printer_print_set)
++#define isl_printer_to_file (*isl_pointers__.p_isl_printer_to_file)
++#define isl_pw_aff_add (*isl_pointers__.p_isl_pw_aff_add)
++#define isl_pw_aff_alloc (*isl_pointers__.p_isl_pw_aff_alloc)
++#define isl_pw_aff_copy (*isl_pointers__.p_isl_pw_aff_copy)
++#define isl_pw_aff_eq_set (*isl_pointers__.p_isl_pw_aff_eq_set)
++#define isl_pw_aff_free (*isl_pointers__.p_isl_pw_aff_free)
++#define isl_pw_aff_from_aff (*isl_pointers__.p_isl_pw_aff_from_aff)
++#define isl_pw_aff_ge_set (*isl_pointers__.p_isl_pw_aff_ge_set)
++#define isl_pw_aff_gt_set (*isl_pointers__.p_isl_pw_aff_gt_set)
++#define isl_pw_aff_is_cst (*isl_pointers__.p_isl_pw_aff_is_cst)
++#define isl_pw_aff_le_set (*isl_pointers__.p_isl_pw_aff_le_set)
++#define isl_pw_aff_lt_set (*isl_pointers__.p_isl_pw_aff_lt_set)
++#define isl_pw_aff_mul (*isl_pointers__.p_isl_pw_aff_mul)
++#define isl_pw_aff_ne_set (*isl_pointers__.p_isl_pw_aff_ne_set)
++#define isl_pw_aff_nonneg_set (*isl_pointers__.p_isl_pw_aff_nonneg_set)
++#define isl_pw_aff_set_tuple_id (*isl_pointers__.p_isl_pw_aff_set_tuple_id)
++#define isl_pw_aff_sub (*isl_pointers__.p_isl_pw_aff_sub)
++#define isl_pw_aff_zero_set (*isl_pointers__.p_isl_pw_aff_zero_set)
++#define isl_schedule_free (*isl_pointers__.p_isl_schedule_free)
++#define isl_schedule_get_band_forest (*isl_pointers__.p_isl_schedule_get_band_forest)
++#define isl_set_add_constraint (*isl_pointers__.p_isl_set_add_constraint)
++#define isl_set_add_dims (*isl_pointers__.p_isl_set_add_dims)
++#define isl_set_apply (*isl_pointers__.p_isl_set_apply)
++#define isl_set_coalesce (*isl_pointers__.p_isl_set_coalesce)
++#define isl_set_copy (*isl_pointers__.p_isl_set_copy)
++#define isl_set_dim (*isl_pointers__.p_isl_set_dim)
++#define isl_set_fix_si (*isl_pointers__.p_isl_set_fix_si)
++#define isl_set_free (*isl_pointers__.p_isl_set_free)
++#define isl_set_get_space (*isl_pointers__.p_isl_set_get_space)
++#define isl_set_get_tuple_id (*isl_pointers__.p_isl_set_get_tuple_id)
++#define isl_set_intersect (*isl_pointers__.p_isl_set_intersect)
++#define isl_set_is_empty (*isl_pointers__.p_isl_set_is_empty)
++#define isl_set_n_dim (*isl_pointers__.p_isl_set_n_dim)
++#define isl_set_nat_universe (*isl_pointers__.p_isl_set_nat_universe)
++#define isl_set_project_out (*isl_pointers__.p_isl_set_project_out)
++#define isl_set_set_tuple_id (*isl_pointers__.p_isl_set_set_tuple_id)
++#define isl_set_universe (*isl_pointers__.p_isl_set_universe)
++#define isl_space_add_dims (*isl_pointers__.p_isl_space_add_dims)
++#define isl_space_alloc (*isl_pointers__.p_isl_space_alloc)
++#define isl_space_copy (*isl_pointers__.p_isl_space_copy)
++#define isl_space_dim (*isl_pointers__.p_isl_space_dim)
++#define isl_space_domain (*isl_pointers__.p_isl_space_domain)
++#define isl_space_find_dim_by_id (*isl_pointers__.p_isl_space_find_dim_by_id)
++#define isl_space_free (*isl_pointers__.p_isl_space_free)
++#define isl_space_from_domain (*isl_pointers__.p_isl_space_from_domain)
++#define isl_space_get_tuple_id (*isl_pointers__.p_isl_space_get_tuple_id)
++#define isl_space_params_alloc (*isl_pointers__.p_isl_space_params_alloc)
++#define isl_space_range (*isl_pointers__.p_isl_space_range)
++#define isl_space_set_alloc (*isl_pointers__.p_isl_space_set_alloc)
++#define isl_space_set_dim_id (*isl_pointers__.p_isl_space_set_dim_id)
++#define isl_space_set_tuple_id (*isl_pointers__.p_isl_space_set_tuple_id)
++#define isl_union_map_add_map (*isl_pointers__.p_isl_union_map_add_map)
++#define isl_union_map_align_params (*isl_pointers__.p_isl_union_map_align_params)
++#define isl_union_map_apply_domain (*isl_pointers__.p_isl_union_map_apply_domain)
++#define isl_union_map_apply_range (*isl_pointers__.p_isl_union_map_apply_range)
++#define isl_union_map_compute_flow (*isl_pointers__.p_isl_union_map_compute_flow)
++#define isl_union_map_copy (*isl_pointers__.p_isl_union_map_copy)
++#define isl_union_map_empty (*isl_pointers__.p_isl_union_map_empty)
++#define isl_union_map_flat_range_product (*isl_pointers__.p_isl_union_map_flat_range_product)
++#define isl_union_map_foreach_map (*isl_pointers__.p_isl_union_map_foreach_map)
++#define isl_union_map_free (*isl_pointers__.p_isl_union_map_free)
++#define isl_union_map_from_map (*isl_pointers__.p_isl_union_map_from_map)
++#define isl_union_map_get_ctx (*isl_pointers__.p_isl_union_map_get_ctx)
++#define isl_union_map_get_space (*isl_pointers__.p_isl_union_map_get_space)
++#define isl_union_map_gist_domain (*isl_pointers__.p_isl_union_map_gist_domain)
++#define isl_union_map_gist_range (*isl_pointers__.p_isl_union_map_gist_range)
++#define isl_union_map_intersect_domain (*isl_pointers__.p_isl_union_map_intersect_domain)
++#define isl_union_map_is_empty (*isl_pointers__.p_isl_union_map_is_empty)
++#define isl_union_map_subtract (*isl_pointers__.p_isl_union_map_subtract)
++#define isl_union_map_union (*isl_pointers__.p_isl_union_map_union)
++#define isl_union_set_add_set (*isl_pointers__.p_isl_union_set_add_set)
++#define isl_union_set_compute_schedule (*isl_pointers__.p_isl_union_set_compute_schedule)
++#define isl_union_set_copy (*isl_pointers__.p_isl_union_set_copy)
++#define isl_union_set_empty (*isl_pointers__.p_isl_union_set_empty)
++#define isl_union_set_from_set (*isl_pointers__.p_isl_union_set_from_set)
++#define isl_aff_add_constant_val (*isl_pointers__.p_isl_aff_add_constant_val)
++#define isl_aff_get_coefficient_val (*isl_pointers__.p_isl_aff_get_coefficient_val)
++#define isl_aff_get_ctx (*isl_pointers__.p_isl_aff_get_ctx)
++#define isl_aff_mod_val (*isl_pointers__.p_isl_aff_mod_val)
++#define isl_ast_build_ast_from_schedule (*isl_pointers__.p_isl_ast_build_ast_from_schedule)
++#define isl_ast_build_free (*isl_pointers__.p_isl_ast_build_free)
++#define isl_ast_build_from_context (*isl_pointers__.p_isl_ast_build_from_context)
++#define isl_ast_build_get_ctx (*isl_pointers__.p_isl_ast_build_get_ctx)
++#define isl_ast_build_get_schedule (*isl_pointers__.p_isl_ast_build_get_schedule)
++#define isl_ast_build_get_schedule_space (*isl_pointers__.p_isl_ast_build_get_schedule_space)
++#define isl_ast_build_set_before_each_for (*isl_pointers__.p_isl_ast_build_set_before_each_for)
++#define isl_ast_build_set_options (*isl_pointers__.p_isl_ast_build_set_options)
++#define isl_ast_expr_free (*isl_pointers__.p_isl_ast_expr_free)
++#define isl_ast_expr_from_val (*isl_pointers__.p_isl_ast_expr_from_val)
++#define isl_ast_expr_get_ctx (*isl_pointers__.p_isl_ast_expr_get_ctx)
++#define isl_ast_expr_get_id (*isl_pointers__.p_isl_ast_expr_get_id)
++#define isl_ast_expr_get_op_arg (*isl_pointers__.p_isl_ast_expr_get_op_arg)
++#define isl_ast_expr_get_op_n_arg (*isl_pointers__.p_isl_ast_expr_get_op_n_arg)
++#define isl_ast_expr_get_op_type (*isl_pointers__.p_isl_ast_expr_get_op_type)
++#define isl_ast_expr_get_type (*isl_pointers__.p_isl_ast_expr_get_type)
++#define isl_ast_expr_get_val (*isl_pointers__.p_isl_ast_expr_get_val)
++#define isl_ast_expr_sub (*isl_pointers__.p_isl_ast_expr_sub)
++#define isl_ast_node_block_get_children (*isl_pointers__.p_isl_ast_node_block_get_children)
++#define isl_ast_node_for_get_body (*isl_pointers__.p_isl_ast_node_for_get_body)
++#define isl_ast_node_for_get_cond (*isl_pointers__.p_isl_ast_node_for_get_cond)
++#define isl_ast_node_for_get_inc (*isl_pointers__.p_isl_ast_node_for_get_inc)
++#define isl_ast_node_for_get_init (*isl_pointers__.p_isl_ast_node_for_get_init)
++#define isl_ast_node_for_get_iterator (*isl_pointers__.p_isl_ast_node_for_get_iterator)
++#define isl_ast_node_free (*isl_pointers__.p_isl_ast_node_free)
++#define isl_ast_node_get_annotation (*isl_pointers__.p_isl_ast_node_get_annotation)
++#define isl_ast_node_get_type (*isl_pointers__.p_isl_ast_node_get_type)
++#define isl_ast_node_if_get_cond (*isl_pointers__.p_isl_ast_node_if_get_cond)
++#define isl_ast_node_if_get_else (*isl_pointers__.p_isl_ast_node_if_get_else)
++#define isl_ast_node_if_get_then (*isl_pointers__.p_isl_ast_node_if_get_then)
++#define isl_ast_node_list_free (*isl_pointers__.p_isl_ast_node_list_free)
++#define isl_ast_node_list_get_ast_node (*isl_pointers__.p_isl_ast_node_list_get_ast_node)
++#define isl_ast_node_list_n_ast_node (*isl_pointers__.p_isl_ast_node_list_n_ast_node)
++#define isl_ast_node_user_get_expr (*isl_pointers__.p_isl_ast_node_user_get_expr)
++#define isl_constraint_set_coefficient_val (*isl_pointers__.p_isl_constraint_set_coefficient_val)
++#define isl_constraint_set_constant_val (*isl_pointers__.p_isl_constraint_set_constant_val)
++#define isl_id_get_user (*isl_pointers__.p_isl_id_get_user)
++#define isl_local_space_get_ctx (*isl_pointers__.p_isl_local_space_get_ctx)
++#define isl_map_fix_val (*isl_pointers__.p_isl_map_fix_val)
++#define isl_options_set_ast_build_atomic_upper_bound (*isl_pointers__.p_isl_options_set_ast_build_atomic_upper_bound)
++#define isl_printer_print_ast_node (*isl_pointers__.p_isl_printer_print_ast_node)
++#define isl_printer_print_str (*isl_pointers__.p_isl_printer_print_str)
++#define isl_printer_set_output_format (*isl_pointers__.p_isl_printer_set_output_format)
++#define isl_pw_aff_mod_val (*isl_pointers__.p_isl_pw_aff_mod_val)
++#define isl_schedule_constraints_compute_schedule (*isl_pointers__.p_isl_schedule_constraints_compute_schedule)
++#define isl_schedule_constraints_on_domain (*isl_pointers__.p_isl_schedule_constraints_on_domain)
++#define isl_schedule_constraints_set_coincidence (*isl_pointers__.p_isl_schedule_constraints_set_coincidence)
++#define isl_schedule_constraints_set_proximity (*isl_pointers__.p_isl_schedule_constraints_set_proximity)
++#define isl_schedule_constraints_set_validity (*isl_pointers__.p_isl_schedule_constraints_set_validity)
++#define isl_set_get_dim_id (*isl_pointers__.p_isl_set_get_dim_id)
++#define isl_set_max_val (*isl_pointers__.p_isl_set_max_val)
++#define isl_set_min_val (*isl_pointers__.p_isl_set_min_val)
++#define isl_set_params (*isl_pointers__.p_isl_set_params)
++#define isl_space_align_params (*isl_pointers__.p_isl_space_align_params)
++#define isl_space_map_from_domain_and_range (*isl_pointers__.p_isl_space_map_from_domain_and_range)
++#define isl_space_set_tuple_name (*isl_pointers__.p_isl_space_set_tuple_name)
++#define isl_space_wrap (*isl_pointers__.p_isl_space_wrap)
++#define isl_union_map_from_domain_and_range (*isl_pointers__.p_isl_union_map_from_domain_and_range)
++#define isl_union_map_range (*isl_pointers__.p_isl_union_map_range)
++#define isl_union_set_union (*isl_pointers__.p_isl_union_set_union)
++#define isl_union_set_universe (*isl_pointers__.p_isl_union_set_universe)
++#define isl_val_2exp (*isl_pointers__.p_isl_val_2exp)
++#define isl_val_add_ui (*isl_pointers__.p_isl_val_add_ui)
++#define isl_val_copy (*isl_pointers__.p_isl_val_copy)
++#define isl_val_free (*isl_pointers__.p_isl_val_free)
++#define isl_val_int_from_si (*isl_pointers__.p_isl_val_int_from_si)
++#define isl_val_int_from_ui (*isl_pointers__.p_isl_val_int_from_ui)
++#define isl_val_mul (*isl_pointers__.p_isl_val_mul)
++#define isl_val_neg (*isl_pointers__.p_isl_val_neg)
++#define isl_val_sub (*isl_pointers__.p_isl_val_sub)
++#define isl_printer_print_union_map (*isl_pointers__.p_isl_printer_print_union_map)
++#define isl_pw_aff_get_ctx (*isl_pointers__.p_isl_pw_aff_get_ctx)
++#define isl_val_is_int (*isl_pointers__.p_isl_val_is_int)
++#define isl_ctx_get_max_operations (*isl_pointers__.p_isl_ctx_get_max_operations)
++#define isl_ctx_set_max_operations (*isl_pointers__.p_isl_ctx_set_max_operations)
++#define isl_ctx_last_error (*isl_pointers__.p_isl_ctx_last_error)
++#define isl_ctx_reset_operations (*isl_pointers__.p_isl_ctx_reset_operations)
++#define isl_map_coalesce (*isl_pointers__.p_isl_map_coalesce)
++#define isl_printer_print_schedule (*isl_pointers__.p_isl_printer_print_schedule)
++#define isl_set_set_dim_id (*isl_pointers__.p_isl_set_set_dim_id)
++#define isl_union_map_coalesce (*isl_pointers__.p_isl_union_map_coalesce)
++#define isl_multi_val_set_val (*isl_pointers__.p_isl_multi_val_set_val)
++#define isl_multi_val_zero (*isl_pointers__.p_isl_multi_val_zero)
++#define isl_options_set_schedule_max_coefficient (*isl_pointers__.p_isl_options_set_schedule_max_coefficient)
++#define isl_options_set_tile_scale_tile_loops (*isl_pointers__.p_isl_options_set_tile_scale_tile_loops)
++#define isl_schedule_copy (*isl_pointers__.p_isl_schedule_copy)
++#define isl_schedule_get_map (*isl_pointers__.p_isl_schedule_get_map)
++#define isl_schedule_map_schedule_node_bottom_up (*isl_pointers__.p_isl_schedule_map_schedule_node_bottom_up)
++#define isl_schedule_node_band_get_permutable (*isl_pointers__.p_isl_schedule_node_band_get_permutable)
++#define isl_schedule_node_band_get_space (*isl_pointers__.p_isl_schedule_node_band_get_space)
++#define isl_schedule_node_band_tile (*isl_pointers__.p_isl_schedule_node_band_tile)
++#define isl_schedule_node_child (*isl_pointers__.p_isl_schedule_node_child)
++#define isl_schedule_node_free (*isl_pointers__.p_isl_schedule_node_free)
++#define isl_schedule_node_get_child (*isl_pointers__.p_isl_schedule_node_get_child)
++#define isl_schedule_node_get_ctx (*isl_pointers__.p_isl_schedule_node_get_ctx)
++#define isl_schedule_node_get_type (*isl_pointers__.p_isl_schedule_node_get_type)
++#define isl_schedule_node_n_children (*isl_pointers__.p_isl_schedule_node_n_children)
++#define isl_union_map_is_equal (*isl_pointers__.p_isl_union_map_is_equal)
++#define isl_union_access_info_compute_flow (*isl_pointers__.p_isl_union_access_info_compute_flow)
++#define isl_union_access_info_from_sink (*isl_pointers__.p_isl_union_access_info_from_sink)
++#define isl_union_access_info_set_may_source (*isl_pointers__.p_isl_union_access_info_set_may_source)
++#define isl_union_access_info_set_must_source (*isl_pointers__.p_isl_union_access_info_set_must_source)
++#define isl_union_access_info_set_schedule (*isl_pointers__.p_isl_union_access_info_set_schedule)
++#define isl_union_flow_free (*isl_pointers__.p_isl_union_flow_free)
++#define isl_union_flow_get_may_dependence (*isl_pointers__.p_isl_union_flow_get_may_dependence)
++#define isl_union_flow_get_must_dependence (*isl_pointers__.p_isl_union_flow_get_must_dependence)
++#define isl_aff_var_on_domain (*isl_pointers__.p_isl_aff_var_on_domain)
++#define isl_multi_aff_from_aff (*isl_pointers__.p_isl_multi_aff_from_aff)
++#define isl_schedule_get_ctx (*isl_pointers__.p_isl_schedule_get_ctx)
++#define isl_multi_aff_set_tuple_id (*isl_pointers__.p_isl_multi_aff_set_tuple_id)
++#define isl_multi_aff_dim (*isl_pointers__.p_isl_multi_aff_dim)
++#define isl_schedule_get_domain (*isl_pointers__.p_isl_schedule_get_domain)
++#define isl_union_set_is_empty (*isl_pointers__.p_isl_union_set_is_empty)
++#define isl_union_set_get_space (*isl_pointers__.p_isl_union_set_get_space)
++#define isl_union_pw_multi_aff_empty (*isl_pointers__.p_isl_union_pw_multi_aff_empty)
++#define isl_union_set_foreach_set (*isl_pointers__.p_isl_union_set_foreach_set)
++#define isl_union_set_free (*isl_pointers__.p_isl_union_set_free)
++#define isl_multi_union_pw_aff_from_union_pw_multi_aff (*isl_pointers__.p_isl_multi_union_pw_aff_from_union_pw_multi_aff)
++#define isl_multi_union_pw_aff_apply_multi_aff (*isl_pointers__.p_isl_multi_union_pw_aff_apply_multi_aff)
++#define isl_schedule_insert_partial_schedule (*isl_pointers__.p_isl_schedule_insert_partial_schedule)
++#define isl_union_pw_multi_aff_free (*isl_pointers__.p_isl_union_pw_multi_aff_free)
++#define isl_pw_multi_aff_project_out_map (*isl_pointers__.p_isl_pw_multi_aff_project_out_map)
++#define isl_union_pw_multi_aff_add_pw_multi_aff (*isl_pointers__.p_isl_union_pw_multi_aff_add_pw_multi_aff)
++#define isl_schedule_from_domain (*isl_pointers__.p_isl_schedule_from_domain)
++#define isl_schedule_sequence (*isl_pointers__.p_isl_schedule_sequence)
++#define isl_ast_build_node_from_schedule (*isl_pointers__.p_isl_ast_build_node_from_schedule)
++#define isl_ast_node_mark_get_node (*isl_pointers__.p_isl_ast_node_mark_get_node)
++#define isl_schedule_node_band_member_get_ast_loop_type (*isl_pointers__.p_isl_schedule_node_band_member_get_ast_loop_type)
++#define isl_schedule_node_band_member_set_ast_loop_type (*isl_pointers__.p_isl_schedule_node_band_member_set_ast_loop_type)
++#define isl_val_n_abs_num_chunks (*isl_pointers__.p_isl_val_n_abs_num_chunks)
++#define isl_val_get_abs_num_chunks (*isl_pointers__.p_isl_val_get_abs_num_chunks)
++#define isl_val_int_from_chunks (*isl_pointers__.p_isl_val_int_from_chunks)
++#define isl_val_is_neg (*isl_pointers__.p_isl_val_is_neg)
++#define isl_version (*isl_pointers__.p_isl_version)
++#define isl_options_get_on_error (*isl_pointers__.p_isl_options_get_on_error)
++#define isl_ctx_reset_error (*isl_pointers__.p_isl_ctx_reset_error)
++
+ typedef struct poly_dr *poly_dr_p;
+
+ typedef struct poly_bb *poly_bb_p;
+@@ -448,5 +1033,6 @@ extern tree cached_scalar_evolution_in_r
+ extern void dot_all_sese (FILE *, vec &);
+ extern void dot_sese (sese_l &);
+ extern void dot_cfg ();
++extern const char *get_isl_version (bool);
+
+ #endif
+--- gcc/graphite.cc.jj 2015-11-04 14:15:32.000000000 +0100
++++ gcc/graphite.cc 2015-11-04 14:56:02.645536409 +0100
+@@ -60,6 +60,35 @@ along with GCC; see the file COPYING3.
+ #include "tree-into-ssa.h"
+ #include "graphite.h"
+
++__typeof (isl_pointers__) isl_pointers__;
++
++static bool
++init_isl_pointers (void)
++{
++ void *h;
++
++ if (isl_pointers__.inited)
++ return isl_pointers__.h != NULL;
++ h = dlopen ("libisl.so.15", RTLD_LAZY);
++ isl_pointers__.h = h;
++ if (h == NULL)
++ return false;
++#define DYNSYM(x) \
++ do \
++ { \
++ union { __typeof (isl_pointers__.p_##x) p; void *q; } u; \
++ u.q = dlsym (h, #x); \
++ if (u.q == NULL) \
++ return false; \
++ isl_pointers__.p_##x = u.p; \
++ } \
++ while (0)
++ DYNSYMS
++#undef DYNSYM
++ isl_pointers__.inited = true;
++ return true;
++}
++
+ /* Print global statistics to FILE. */
+
+ static void
+@@ -365,6 +394,15 @@ graphite_transform_loops (void)
+ if (parallelized_function_p (cfun->decl))
+ return;
+
++ if (number_of_loops (cfun) <= 1)
++ return;
++
++ if (!init_isl_pointers ())
++ {
++ sorry ("Graphite loop optimizations cannot be used");
++ return;
++ }
++
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ /* We rely on post-dominators during merging of SESE regions so those
+@@ -455,6 +493,14 @@ graphite_transform_loops (void)
+ }
+ }
+
++const char *
++get_isl_version (bool force)
++{
++ if (force)
++ init_isl_pointers ();
++ return (isl_pointers__.inited && isl_version) ? isl_version () : "none";
++}
++
+ #else /* If isl is not available: #ifndef HAVE_isl. */
+
+ static void
+--- gcc/toplev.cc.jj 2017-02-19 13:02:31.000000000 +0100
++++ gcc/toplev.cc 2017-02-19 16:50:25.536301350 +0100
+@@ -94,6 +94,7 @@ along with GCC; see the file COPYING3.
+
+ #ifdef HAVE_isl
+ #include
++extern const char *get_isl_version (bool);
+ #endif
+
+ static void general_init (const char *, bool);
+@@ -683,7 +684,7 @@ print_version (FILE *file, const char *i
+ #ifndef HAVE_isl
+ "none"
+ #else
+- isl_version ()
++ get_isl_version (*indent == 0)
+ #endif
+ );
+ if (strcmp (GCC_GMP_STRINGIFY_VERSION, gmp_version))
diff --git a/gcc12-isl-dl2.patch b/gcc12-isl-dl2.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5402a8edff42bf8087b92ccd42f9a6f284d242d9
--- /dev/null
+++ b/gcc12-isl-dl2.patch
@@ -0,0 +1,71 @@
+2011-04-04 Jakub Jelinek
+
+ * toplev.cc (toplev_main_argv): New variable.
+ (toplev_main): Initialize it.
+ * graphite.cc (init_isl_pointers): Load libisl.so.15 from gcc's private
+ directory.
+
+--- gcc/toplev.cc.jj 2008-12-09 23:59:10.000000000 +0100
++++ gcc/toplev.cc 2009-01-27 14:33:52.000000000 +0100
+@@ -113,6 +113,8 @@ static void finalize (bool);
+ static void crash_signal (int) ATTRIBUTE_NORETURN;
+ static void compile_file (void);
+
++const char **toplev_main_argv;
++
+ /* Decoded options, and number of such options. */
+ struct cl_decoded_option *save_decoded_options;
+ unsigned int save_decoded_options_count;
+@@ -2239,6 +2241,8 @@ toplev::main (int argc, char **argv)
+
+ expandargv (&argc, &argv);
+
++ toplev_main_argv = CONST_CAST2 (const char **, char **, argv);
++
+ /* Initialization of GCC's environment, and diagnostics. */
+ general_init (argv[0], m_init_signals);
+
+--- gcc/graphite.cc.jj 2010-12-01 10:24:32.000000000 -0500
++++ gcc/graphite.cc 2010-12-01 11:46:07.832118193 -0500
+@@ -64,11 +64,39 @@ __typeof (isl_pointers__) isl_pointers__
+ static bool
+ init_isl_pointers (void)
+ {
+- void *h;
++ void *h = NULL;
++ extern const char **toplev_main_argv;
++ char *buf, *p;
++ size_t len;
+
+ if (isl_pointers__.inited)
+ return isl_pointers__.h != NULL;
+- h = dlopen ("libisl.so.15", RTLD_LAZY);
++ len = progname - toplev_main_argv[0];
++ buf = XALLOCAVAR (char, len + sizeof "libisl.so.15");
++ memcpy (buf, toplev_main_argv[0], len);
++ strcpy (buf + len, "libisl.so.15");
++ len += sizeof "libisl.so.15";
++ p = strstr (buf, "/libexec/");
++ if (p != NULL)
++ {
++ while (1)
++ {
++ char *q = strstr (p + 8, "/libexec/");
++ if (q == NULL)
++ break;
++ p = q;
++ }
++ memmove (p + 4, p + 8, len - (p + 8 - buf));
++ h = dlopen (buf, RTLD_LAZY);
++ if (h == NULL)
++ {
++ len = progname - toplev_main_argv[0];
++ memcpy (buf, toplev_main_argv[0], len);
++ strcpy (buf + len, "libisl.so.15");
++ }
++ }
++ if (h == NULL)
++ h = dlopen (buf, RTLD_LAZY);
+ isl_pointers__.h = h;
+ if (h == NULL)
+ return false;
diff --git a/gcc12-libgomp-omp_h-multilib.patch b/gcc12-libgomp-omp_h-multilib.patch
new file mode 100644
index 0000000000000000000000000000000000000000..d0e98d19833d7093347ccf6a44a127e0d67f1b1a
--- /dev/null
+++ b/gcc12-libgomp-omp_h-multilib.patch
@@ -0,0 +1,17 @@
+2008-06-09 Jakub Jelinek
+
+ * omp.h.in (omp_nest_lock_t): Fix up for Linux multilibs.
+
+--- libgomp/omp.h.in.jj 2008-06-09 13:34:05.000000000 +0200
++++ libgomp/omp.h.in 2008-06-09 13:34:48.000000000 +0200
+@@ -42,8 +42,8 @@ typedef struct
+
+ typedef struct
+ {
+- unsigned char _x[@OMP_NEST_LOCK_SIZE@]
+- __attribute__((__aligned__(@OMP_NEST_LOCK_ALIGN@)));
++ unsigned char _x[8 + sizeof (void *)]
++ __attribute__((__aligned__(sizeof (void *))));
+ } omp_nest_lock_t;
+ #endif
+
diff --git a/gcc12-libstdc++-docs.patch b/gcc12-libstdc++-docs.patch
new file mode 100644
index 0000000000000000000000000000000000000000..cdcd435ff35b49331a0c5d8175d570afea0f3105
--- /dev/null
+++ b/gcc12-libstdc++-docs.patch
@@ -0,0 +1,24 @@
+--- libstdc++-v3/doc/html/index.html.jj 2011-01-03 12:53:21.282829010 +0100
++++ libstdc++-v3/doc/html/index.html 2011-01-04 18:06:28.999851145 +0100
+@@ -5,6 +5,8 @@
+ FSF
+
+
++ Release 12.0.1
++
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation
+ License, Version 1.2 or any later version published by the
+--- libstdc++-v3/doc/html/api.html.jj 2011-01-03 12:53:21.000000000 +0100
++++ libstdc++-v3/doc/html/api.html 2011-01-04 18:12:01.672757784 +0100
+@@ -20,7 +20,9 @@
+ member functions for the library classes, finding out what is in a
+ particular include file, looking at inheritance diagrams, etc.
+
+- The API documentation, rendered into HTML, can be viewed online
++ The API documentation, rendered into HTML, can be viewed locally
++ for the 12.0.1 release,
++ online
+ for each GCC release
+ and
+
diff --git a/gcc12-libtool-no-rpath.patch b/gcc12-libtool-no-rpath.patch
new file mode 100644
index 0000000000000000000000000000000000000000..466c661e0c182ef0b37bb7dcefa8eba0c7668c65
--- /dev/null
+++ b/gcc12-libtool-no-rpath.patch
@@ -0,0 +1,27 @@
+libtool sucks.
+--- ltmain.sh.jj 2007-12-07 14:53:21.000000000 +0100
++++ ltmain.sh 2008-09-05 21:51:48.000000000 +0200
+@@ -5394,6 +5394,7 @@ EOF
+ rpath="$finalize_rpath"
+ test "$mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
++ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+@@ -6071,6 +6072,7 @@ EOF
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
++ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+@@ -6120,6 +6122,7 @@ EOF
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
++ case "$libdir" in /usr/lib|/usr/lib64|/usr/lib/../lib|/usr/lib/../lib64) continue;; esac
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
diff --git a/gcc12-no-add-needed.patch b/gcc12-no-add-needed.patch
new file mode 100644
index 0000000000000000000000000000000000000000..5817299b0d75522e9ee5c781567bfebe3a2d0687
--- /dev/null
+++ b/gcc12-no-add-needed.patch
@@ -0,0 +1,37 @@
+2010-02-08 Roland McGrath
+
+ * config/gnu-user.h (LINK_EH_SPEC): Pass --no-add-needed to the linker.
+ * config/alpha/elf.h (LINK_EH_SPEC): Likewise.
+ * config/ia64/linux.h (LINK_EH_SPEC): Likewise.
+
+--- gcc/config/alpha/elf.h.jj 2011-01-03 12:52:31.118056764 +0100
++++ gcc/config/alpha/elf.h 2011-01-04 18:14:10.931874160 +0100
+@@ -168,5 +168,5 @@ extern int alpha_this_gpdisp_sequence_nu
+ I imagine that other systems will catch up. In the meantime, it
+ doesn't harm to make sure that the data exists to be used later. */
+ #if defined(HAVE_LD_EH_FRAME_HDR)
+-#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} "
++#define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} "
+ #endif
+--- gcc/config/ia64/linux.h.jj 2011-01-03 13:02:11.462994522 +0100
++++ gcc/config/ia64/linux.h 2011-01-04 18:14:10.931874160 +0100
+@@ -76,7 +76,7 @@ do { \
+ Signalize that because we have fde-glibc, we don't need all C shared libs
+ linked against -lgcc_s. */
+ #undef LINK_EH_SPEC
+-#define LINK_EH_SPEC ""
++#define LINK_EH_SPEC "--no-add-needed "
+
+ #undef TARGET_INIT_LIBFUNCS
+ #define TARGET_INIT_LIBFUNCS ia64_soft_fp_init_libfuncs
+--- gcc/config/gnu-user.h.jj 2011-01-03 12:53:03.739057299 +0100
++++ gcc/config/gnu-user.h 2011-01-04 18:14:10.932814884 +0100
+@@ -106,7 +106,7 @@ see the files COPYING3 and COPYING.RUNTI
+ #define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
+
+ #if defined(HAVE_LD_EH_FRAME_HDR)
+-#define LINK_EH_SPEC "%{!static|static-pie:--eh-frame-hdr} "
++#define LINK_EH_SPEC "--no-add-needed %{!static|static-pie:--eh-frame-hdr} "
+ #endif
+
+ #define GNU_USER_TARGET_LINK_GCC_C_SEQUENCE_SPEC \
diff --git a/gcc12-pr104253.patch b/gcc12-pr104253.patch
new file mode 100644
index 0000000000000000000000000000000000000000..55605242da021161d9859d2cff7fd67055d9df25
--- /dev/null
+++ b/gcc12-pr104253.patch
@@ -0,0 +1,200 @@
+If you are on a PowerPC system where the default long double is IEEE
+128-bit, GCC will use the wrong names for some of the conversion functions
+for the __ibm128 type.
+
+What is happening is when the defult long double is IEEE 128-bit, the
+various convert, truncation, and extend functions did not specify a
+default name for the conversion. The machine indepentent portions of the
+compiler would construct a call with an 'if' name (IFmode being the mode
+for IBM 128-bit floating point). This patch specifies to use the
+tradiational 'tf' name for these conversion functions.
+
+2022-01-28 Michael Meissner
+
+gcc/
+ PR target/104253
+ * config/rs6000/rs6000.cc (init_float128_ibm): Use the TF names
+ for builtin conversions between __ibm128 and DImode when long
+ double uses the IEEE 128-bit format.
+
+gcc/testsuite/
+ PR target/104253
+ * gcc.target/powerpc/pr104253.c: New test.
+---
+ gcc/config/rs6000/rs6000.cc | 6 +
+ gcc/testsuite/gcc.target/powerpc/pr104253.c | 154 ++++++++++++++++++++
+ 2 files changed, 160 insertions(+)
+ create mode 100644 gcc/testsuite/gcc.target/powerpc/pr104253.c
+
+--- gcc/config/rs6000/rs6000.cc
++++ gcc/config/rs6000/rs6000.cc
+@@ -11113,6 +11113,12 @@ init_float128_ibm (machine_mode mode)
+ set_conv_libfunc (trunc_optab, DDmode, mode, "__dpd_trunctfdd");
+ set_conv_libfunc (sext_optab, TDmode, mode, "__dpd_extendtftd");
+
++ set_conv_libfunc (sfix_optab, DImode, mode, "__fixtfdi");
++ set_conv_libfunc (ufix_optab, DImode, mode, "__fixunstfdi");
++
++ set_conv_libfunc (sfloat_optab, mode, DImode, "__floatditf");
++ set_conv_libfunc (ufloat_optab, mode, DImode, "__floatunditf");
++
+ if (TARGET_POWERPC64)
+ {
+ set_conv_libfunc (sfix_optab, TImode, mode, "__fixtfti");
+--- gcc/testsuite/gcc.target/powerpc/pr104253.c
++++ gcc/testsuite/gcc.target/powerpc/pr104253.c
+@@ -0,0 +1,154 @@
++/*
++ * Require float128 support because __ibm128 currently is not enabled unless we
++ * also have __float128 support.
++ */
++
++/* { dg-do run } */
++/* { require-effective-target ppc_float128_sw } */
++/* { dg-options "-O2 -mvsx -mfloat128" } */
++
++/*
++ * PR target/104253
++ *
++ * Verify that the various conversions to and from __ibm128 work. When the
++ * default for long double is changed to IEEE 128-bit, originally GCC would
++ * call the functions using an 'if' name instead of 'tf.
++ */
++
++#include
++
++extern float ibm128_to_sf (__ibm128) __attribute__((noinline));
++extern double ibm128_to_df (__ibm128) __attribute__((noinline));
++extern int ibm128_to_si (__ibm128) __attribute__((noinline));
++extern long long ibm128_to_di (__ibm128) __attribute__((noinline));
++extern unsigned int ibm128_to_usi (__ibm128) __attribute__((noinline));
++extern unsigned long long ibm128_to_udi (__ibm128) __attribute__((noinline));
++
++extern __ibm128 sf_to_ibm128 (float) __attribute__((noinline));
++extern __ibm128 df_to_ibm128 (double) __attribute__((noinline));
++extern __ibm128 si_to_ibm128 (int) __attribute__((noinline));
++extern __ibm128 di_to_ibm128 (long long) __attribute__((noinline));
++extern __ibm128 usi_to_ibm128 (unsigned int) __attribute__((noinline));
++extern __ibm128 udi_to_ibm128 (unsigned long long) __attribute__((noinline));
++
++float
++ibm128_to_sf (__ibm128 x)
++{
++ return x;
++}
++
++double
++ibm128_to_df (__ibm128 x)
++{
++ return x;
++}
++
++int
++ibm128_to_si (__ibm128 x)
++{
++ return x;
++}
++
++long long
++ibm128_to_di (__ibm128 x)
++{
++ return x;
++}
++
++unsigned int
++ibm128_to_usi (__ibm128 x)
++{
++ return x;
++}
++
++unsigned long long
++ibm128_to_udi (__ibm128 x)
++{
++ return x;
++}
++
++__ibm128
++sf_to_ibm128 (float x)
++{
++ return x;
++}
++
++__ibm128
++df_to_ibm128 (double x)
++{
++ return x;
++}
++
++__ibm128
++si_to_ibm128 (int x)
++{
++ return x;
++}
++
++__ibm128
++di_to_ibm128 (long long x)
++{
++ return x;
++}
++
++__ibm128
++usi_to_ibm128 (unsigned int x)
++{
++ return x;
++}
++
++__ibm128
++udi_to_ibm128 (unsigned long long x)
++{
++ return x;
++}
++
++volatile float seven_sf = 7.0f;
++volatile double seven_df = 7.0;
++volatile int seven_si = 7;
++volatile long long seven_di = 7LL;
++volatile unsigned int seven_usi = 7U;
++volatile unsigned long long seven_udi = 7ULL;
++volatile __ibm128 seven_ibm128 = 7.0;
++
++int
++main (void)
++{
++ if (seven_ibm128 != sf_to_ibm128 (seven_sf))
++ abort ();
++
++ if (seven_ibm128 != df_to_ibm128 (seven_df))
++ abort ();
++
++ if (seven_ibm128 != si_to_ibm128 (seven_si))
++ abort ();
++
++ if (seven_ibm128 != di_to_ibm128 (seven_di))
++ abort ();
++
++ if (seven_ibm128 != usi_to_ibm128 (seven_usi))
++ abort ();
++
++ if (seven_ibm128 != udi_to_ibm128 (seven_udi))
++ abort ();
++
++ if (seven_sf != ibm128_to_sf (seven_ibm128))
++ abort ();
++
++ if (seven_df != ibm128_to_df (seven_ibm128))
++ abort ();
++
++ if (seven_si != ibm128_to_si (seven_ibm128))
++ abort ();
++
++ if (seven_di != ibm128_to_di (seven_ibm128))
++ abort ();
++
++ if (seven_usi != ibm128_to_usi (seven_ibm128))
++ abort ();
++
++ if (seven_udi != ibm128_to_udi (seven_ibm128))
++ abort ();
++
++ return 0;
++}
diff --git a/gcc12-rh1574936.patch b/gcc12-rh1574936.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6b4be0cc9744677ba5573689f8b56ceb63a4737e
--- /dev/null
+++ b/gcc12-rh1574936.patch
@@ -0,0 +1,30 @@
+crt files and statically linked libgcc objects cause false positives
+in annobin coverage, so we add the assembler flag to generate notes
+for them.
+
+The patch also adds notes to libgcc_s.so, but this is harmless because
+these notes only confer that there is no other annobin markup.
+
+2018-07-25 Florian Weimer
+
+ * Makefile.in (LIBGCC2_CFLAGS, CRTSTUFF_CFLAGS): Add
+ -Wa,--generate-missing-build-notes=yes.
+
+--- libgcc/Makefile.in 2018-01-13 13:05:41.000000000 +0100
++++ libgcc/Makefile.in 2018-07-25 13:15:02.036226940 +0200
+@@ -246,6 +246,7 @@ LIBGCC2_DEBUG_CFLAGS = -g
+ LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
+ $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \
+ -fbuilding-libgcc -fno-stack-protector \
++ -Wa,--generate-missing-build-notes=yes \
+ $(INHIBIT_LIBC_CFLAGS)
+
+ # Additional options to use when compiling libgcc2.a.
+@@ -301,6 +302,7 @@ CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(IN
+ $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \
+ -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
+ -fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \
++ -Wa,--generate-missing-build-notes=yes \
+ $(INHIBIT_LIBC_CFLAGS) $(USE_TM_CLONE_REGISTRY)
+
+ # Extra flags to use when compiling crt{begin,end}.o.
diff --git a/gcc12-sparc-config-detection.patch b/gcc12-sparc-config-detection.patch
new file mode 100644
index 0000000000000000000000000000000000000000..bb06b35d02b537cc34de9ab7865d81beb58d37e4
--- /dev/null
+++ b/gcc12-sparc-config-detection.patch
@@ -0,0 +1,40 @@
+--- gcc/config.gcc.jj 2008-04-24 15:42:46.000000000 -0500
++++ gcc/config.gcc 2008-04-24 15:44:51.000000000 -0500
+@@ -2790,7 +2790,7 @@ sparc-*-rtems*)
+ tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/sp-elf.h sparc/rtemself.h rtems.h newlib-stdint.h"
+ tmake_file="${tmake_file} sparc/t-sparc sparc/t-rtems"
+ ;;
+-sparc-*-linux*)
++sparc-*-linux* | sparcv9-*-linux*)
+ tm_file="${tm_file} dbxelf.h elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/tso.h"
+ extra_options="${extra_options} sparc/long-double-switch.opt"
+ case ${target} in
+@@ -2844,7 +2844,7 @@ sparc64-*-rtems*)
+ extra_options="${extra_options}"
+ tmake_file="${tmake_file} sparc/t-sparc sparc/t-rtems-64"
+ ;;
+-sparc64-*-linux*)
++sparc64*-*-linux*)
+ tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h sparc/sysv4.h gnu-user.h linux.h glibc-stdint.h sparc/default64.h sparc/linux64.h sparc/tso.h"
+ extra_options="${extra_options} sparc/long-double-switch.opt"
+ tmake_file="${tmake_file} sparc/t-sparc sparc/t-linux64"
+--- libgcc/config.host.jj 2008-04-24 15:46:19.000000000 -0500
++++ libgcc/config.host 2008-04-24 15:46:49.000000000 -0500
+@@ -1002,7 +1002,7 @@ sparc-*-elf*)
+ tmake_file="${tmake_file} t-fdpbit t-crtfm"
+ extra_parts="$extra_parts crti.o crtn.o crtfastmath.o"
+ ;;
+-sparc-*-linux*) # SPARC's running GNU/Linux, libc6
++sparc-*-linux* | sparcv9-*-linux*) # SPARC's running GNU/Linux, libc6
+ tmake_file="${tmake_file} t-crtfm"
+ if test "${host_address}" = 64; then
+ tmake_file="$tmake_file sparc/t-linux64"
+@@ -1050,7 +1050,7 @@ sparc64-*-freebsd*|ultrasparc-*-freebsd*
+ tmake_file="$tmake_file t-crtfm"
+ extra_parts="$extra_parts crtfastmath.o"
+ ;;
+-sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux
++sparc64*-*-linux*) # 64-bit SPARC's running GNU/Linux
+ extra_parts="$extra_parts crtfastmath.o"
+ tmake_file="${tmake_file} t-crtfm sparc/t-linux"
+ if test "${host_address}" = 64; then
diff --git a/isl-0.18.tar.bz2 b/isl-0.18.tar.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..4c8296cb72a25bbb2ef698c729855dfe7dbfa10d
Binary files /dev/null and b/isl-0.18.tar.bz2 differ
diff --git a/newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz b/newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz
new file mode 100644
index 0000000000000000000000000000000000000000..38097b3a9dc937ec9d8772abe1923900a6f3b105
Binary files /dev/null and b/newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz differ
diff --git a/nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz b/nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz
new file mode 100644
index 0000000000000000000000000000000000000000..2740609a65eadb8407fcb8439f3a10d9daf7855f
Binary files /dev/null and b/nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz differ