diff options
author | Michael Hirsch, Ph.D <scivision@users.noreply.github.com> | 2019-11-12 14:44:28 -0500 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2019-11-25 13:08:56 +0200 |
commit | 07a2fe2f00122b514a5119b724581ea020d2c6ea (patch) | |
tree | fb3577660d7cb61519da2cc70640e84dbbe3ead0 | |
parent | 8313e8fd54c95459efbc413bb60d460cce10a12b (diff) | |
download | meson-07a2fe2f00122b514a5119b724581ea020d2c6ea.zip meson-07a2fe2f00122b514a5119b724581ea020d2c6ea.tar.gz meson-07a2fe2f00122b514a5119b724581ea020d2c6ea.tar.bz2 |
complete gfortran/intel/intel-cl fortran_std test
-rw-r--r-- | docs/markdown/Builtin-options.md | 1 | ||||
-rw-r--r-- | docs/markdown/Configuring-a-build-directory.md | 1 | ||||
-rw-r--r-- | docs/markdown/snippets/fortran_std.md | 14 | ||||
-rw-r--r-- | mesonbuild/compilers/fortran.py | 54 | ||||
-rw-r--r-- | test cases/fortran/19 fortran_std/legacy.f | 7 | ||||
-rw-r--r-- | test cases/fortran/19 fortran_std/meson.build | 27 | ||||
-rw-r--r-- | test cases/fortran/19 fortran_std/std2003.f90 | 36 | ||||
-rw-r--r-- | test cases/fortran/19 fortran_std/std2008.f90 | 32 | ||||
-rw-r--r-- | test cases/fortran/19 fortran_std/std2018.f90 | 34 | ||||
-rw-r--r-- | test cases/fortran/19 fortran_std/std95.f90 | 13 |
10 files changed, 218 insertions, 1 deletions
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md index f406067..9eac371 100644 --- a/docs/markdown/Builtin-options.md +++ b/docs/markdown/Builtin-options.md @@ -146,6 +146,7 @@ compiler being used: | cpp_eh | default | none, default, a, s, sc | C++ exception handling type | | cpp_rtti | true | true, false | Whether to enable RTTI (runtime type identification) | | cpp_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against | +| fortran_std | none | [none, legacy, f95, f2003, f2008, f2018] | Fortran language standard to use | The default values of `c_winlibs` and `cpp_winlibs` are in compiler-specific argument forms, but the libraries are: kernel32, user32, gdi32, winspool, diff --git a/docs/markdown/Configuring-a-build-directory.md b/docs/markdown/Configuring-a-build-directory.md index b0fb574..1387a46 100644 --- a/docs/markdown/Configuring-a-build-directory.md +++ b/docs/markdown/Configuring-a-build-directory.md @@ -65,6 +65,7 @@ sample output for a simple project. cpp_debugstl false [true, false] STL debug mode cpp_link_args [] Extra arguments passed to the C++ linker cpp_std c++11 [none, c++98, c++03, c++11, c++14, c++17, c++1z, c++2a, gnu++03, gnu++11, gnu++14, gnu++17, gnu++1z, gnu++2a] C++ language standard to use + fortran_std [] [none, legacy, f95, f2003, f2008, f2018] language standard to use Directories: Option Current Value Description diff --git a/docs/markdown/snippets/fortran_std.md b/docs/markdown/snippets/fortran_std.md new file mode 100644 index 0000000..2170a5e --- /dev/null +++ b/docs/markdown/snippets/fortran_std.md @@ -0,0 +1,14 @@ +## `fortran_std` option + +**new in 0.53.0** +Akin to the `c_std` and `cpp_std` options, the `fortran_std` option sets Fortran compilers to warn or error on non-Fortran standard code. +Only the Gfortran and Intel Fortran compilers have support for this option. +Other Fortran compilers ignore the `fortran_std` option. + +Supported values for `fortran_std` include: + +* `legacy` for non-conforming code--this is especially important for Gfortran, which by default errors on old non-compliant Fortran code +* `f95` for Fortran 95 compliant code. +* `f2003` for Fortran 2003 compliant code. +* `f2008` for Fortran 2008 compliant code. +* `f2018` for Fortran 2018 compliant code.
\ No newline at end of file diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 5a2766e..3003fcd 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -17,6 +17,7 @@ from typing import List import subprocess, os import typing +from .. import coredata from .compilers import ( clike_debug_args, Compiler, @@ -32,7 +33,7 @@ from .mixins.pgi import PGICompiler from .. import mlog from mesonbuild.mesonlib import ( - EnvironmentException, MesonException, MachineChoice, LibType + version_compare, EnvironmentException, MesonException, MachineChoice, LibType ) if typing.TYPE_CHECKING: @@ -179,6 +180,25 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): '2': default_warn_args + ['-Wextra'], '3': default_warn_args + ['-Wextra', '-Wpedantic', '-fimplicit-none']} + def get_options(self): + opts = FortranCompiler.get_options(self) + fortran_stds = ['legacy', 'f95', 'f2003'] + if version_compare(self.version, '>=4.4.0'): + fortran_stds += ['f2008'] + if version_compare(self.version, '>=8.0.0'): + fortran_stds += ['f2018'] + opts.update({'fortran_std': coredata.UserComboOption('Fortran language standard to use', + ['none'] + fortran_stds, + 'none')}) + return opts + + def get_option_compile_args(self, options) -> typing.List[str]: + args = [] + std = options['fortran_std'] + if std.value != 'none': + args.append('-std=' + std.value) + return args + def get_dependency_gen_args(self, outtarget, outfile): # Disabled until this is fixed: # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62162 @@ -269,6 +289,22 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): '2': default_warn_args + ['-warn', 'unused'], '3': ['-warn', 'all']} + def get_options(self): + opts = FortranCompiler.get_options(self) + fortran_stds = ['legacy', 'f95', 'f2003', 'f2008', 'f2018'] + opts.update({'fortran_std': coredata.UserComboOption('Fortran language standard to use', + ['none'] + fortran_stds, + 'none')}) + return opts + + def get_option_compile_args(self, options) -> typing.List[str]: + args = [] + std = options['fortran_std'] + stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} + if std.value != 'none': + args.append('-stand=' + stds[std.value]) + return args + def get_preprocess_only_args(self): return ['-cpp', '-EP'] @@ -312,6 +348,22 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler): '2': default_warn_args + ['/warn:unused'], '3': ['/warn:all']} + def get_options(self): + opts = FortranCompiler.get_options(self) + fortran_stds = ['legacy', 'f95', 'f2003', 'f2008', 'f2018'] + opts.update({'fortran_std': coredata.UserComboOption('Fortran language standard to use', + ['none'] + fortran_stds, + 'none')}) + return opts + + def get_option_compile_args(self, options) -> typing.List[str]: + args = [] + std = options['fortran_std'] + stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} + if std.value != 'none': + args.append('/stand:' + stds[std.value]) + return args + def get_module_outdir_args(self, path) -> List[str]: return ['/module:' + path] diff --git a/test cases/fortran/19 fortran_std/legacy.f b/test cases/fortran/19 fortran_std/legacy.f new file mode 100644 index 0000000..339064d --- /dev/null +++ b/test cases/fortran/19 fortran_std/legacy.f @@ -0,0 +1,7 @@ + ! non-integer loop indices are deleted in Fortran 95 standard + real a + + do 10 a=0,0.5,0.1 +10 continue + + end program
\ No newline at end of file diff --git a/test cases/fortran/19 fortran_std/meson.build b/test cases/fortran/19 fortran_std/meson.build new file mode 100644 index 0000000..f46f8ff --- /dev/null +++ b/test cases/fortran/19 fortran_std/meson.build @@ -0,0 +1,27 @@ +project('FortranStd', 'fortran', + default_options: ['warning_level=0']) +# As with C and C++, each Fortran compiler + version has a subset of supported Fortran standards +# Additionally, a necessary option for non-standard Fortran projects is the "legacy" +# option, which allows non-standard syntax and behavior quirks. +# Thus "legacy" is a necessity for some old but important Fortran projects. +# By default, popular Fortran compilers disallow these quirks without "legacy" option. + +fc = meson.get_compiler('fortran') + +executable('stdnone', 'std95.f90') + +executable('std_legacy', 'legacy.f', override_options : ['fortran_std=legacy']) + +executable('std_95', 'std95.f90', override_options : ['fortran_std=f95']) + +executable('std_f2003', 'std2003.f90', override_options : ['fortran_std=f2003']) + +executable('std_f2008', 'std2008.f90', override_options : ['fortran_std=f2008']) + +if fc.get_id() == 'gcc' + if fc.version().version_compare('>=8.0') + executable('std_f2018', 'std2018.f90', override_options : ['fortran_std=f2018']) + endif +else + executable('std_f2018', 'std2018.f90', override_options : ['fortran_std=f2018']) +endif
\ No newline at end of file diff --git a/test cases/fortran/19 fortran_std/std2003.f90 b/test cases/fortran/19 fortran_std/std2003.f90 new file mode 100644 index 0000000..08d2f50 --- /dev/null +++ b/test cases/fortran/19 fortran_std/std2003.f90 @@ -0,0 +1,36 @@ +use, intrinsic :: iso_fortran_env, only : error_unit +implicit none + +! http://fortranwiki.org/fortran/show/Real+precision +integer, parameter :: sp = selected_real_kind(6, 37) +integer, parameter :: dp = selected_real_kind(15, 307) + +real(sp) :: a32 +real(dp) :: a64 + +real(sp), parameter :: pi32 = 4*atan(1._sp) +real(dp), parameter :: pi64 = 4*atan(1._dp) + +if (pi32 == pi64) stop 1 + +call timestwo(a32) +call timestwo(a64) + +contains + +elemental subroutine timestwo(a) + +class(*), intent(inout) :: a + +select type (a) + type is (real(sp)) + a = 2*a + type is (real(dp)) + a = 2*a + type is (integer) + a = 2*a +end select + +end subroutine timestwo + +end program
\ No newline at end of file diff --git a/test cases/fortran/19 fortran_std/std2008.f90 b/test cases/fortran/19 fortran_std/std2008.f90 new file mode 100644 index 0000000..e7887ae --- /dev/null +++ b/test cases/fortran/19 fortran_std/std2008.f90 @@ -0,0 +1,32 @@ +use, intrinsic :: iso_fortran_env, only : error_unit, sp=>real32, dp=>real64 +implicit none + +real(sp) :: a32 +real(dp) :: a64 + +real(sp), parameter :: pi32 = 4*atan(1._sp) +real(dp), parameter :: pi64 = 4*atan(1._dp) + +if (pi32 == pi64) error stop 'real32 values generally do not exactly equal real64 values' + +call timestwo(a32) +call timestwo(a64) + +contains + +elemental subroutine timestwo(a) + +class(*), intent(inout) :: a + +select type (a) + type is (real(sp)) + a = 2*a + type is (real(dp)) + a = 2*a + type is (integer) + a = 2*a +end select + +end subroutine timestwo + +end program
\ No newline at end of file diff --git a/test cases/fortran/19 fortran_std/std2018.f90 b/test cases/fortran/19 fortran_std/std2018.f90 new file mode 100644 index 0000000..9a326b1 --- /dev/null +++ b/test cases/fortran/19 fortran_std/std2018.f90 @@ -0,0 +1,34 @@ +use, intrinsic :: iso_fortran_env, only : error_unit, sp=>real32, dp=>real64 +implicit none + +real(sp) :: a32 +real(dp) :: a64 + +real(sp), parameter :: pi32 = 4*atan(1._sp) +real(dp), parameter :: pi64 = 4*atan(1._dp) + +if (pi32 == pi64) error stop 'real32 values generally do not exactly equal real64 values' + +call timestwo(a32) +call timestwo(a64) + +contains + +elemental subroutine timestwo(a) + +class(*), intent(inout) :: a + +select type (a) + type is (real(sp)) + a = 2*a + type is (real(dp)) + a = 2*a + type is (integer) + a = 2*a + class default + error stop 'requires real32, real64 or integer' +end select + +end subroutine timestwo + +end program
\ No newline at end of file diff --git a/test cases/fortran/19 fortran_std/std95.f90 b/test cases/fortran/19 fortran_std/std95.f90 new file mode 100644 index 0000000..8518df1 --- /dev/null +++ b/test cases/fortran/19 fortran_std/std95.f90 @@ -0,0 +1,13 @@ +implicit none + +integer :: i, j +integer, parameter :: N=3 +real :: A(N,N) + +A = 0 + +forall (i=1:N, j=1:N) + A(i,j) = 1 +end forall + +end program
\ No newline at end of file |