diff options
Diffstat (limited to 'test cases/fortran')
76 files changed, 1036 insertions, 0 deletions
diff --git a/test cases/fortran/1 basic/meson.build b/test cases/fortran/1 basic/meson.build new file mode 100644 index 0000000..52e2d6f --- /dev/null +++ b/test cases/fortran/1 basic/meson.build @@ -0,0 +1,13 @@ +project('simple fortran', 'fortran') + +fc = meson.get_compiler('fortran') +if fc.get_id() == 'gcc' + add_global_arguments('-fbounds-check', language : 'fortran') +endif + +args = fc.first_supported_argument(['-ffree-form', '-free', '/free']) +assert(args != [], 'No arguments found?') + +e = executable('simple', 'simple.f90', + fortran_args : args) +test('Simple Fortran', e) diff --git a/test cases/fortran/1 basic/simple.f90 b/test cases/fortran/1 basic/simple.f90 new file mode 100644 index 0000000..2160d56 --- /dev/null +++ b/test cases/fortran/1 basic/simple.f90 @@ -0,0 +1,3 @@ +program main +print *, "Fortran compilation is working." +end program diff --git a/test cases/fortran/10 find library/gzip.f90 b/test cases/fortran/10 find library/gzip.f90 new file mode 100644 index 0000000..32f21d7 --- /dev/null +++ b/test cases/fortran/10 find library/gzip.f90 @@ -0,0 +1,32 @@ +module gzip + +use iso_c_binding, only: c_char, c_ptr, c_int +implicit none + +interface +type(c_ptr) function gzopen(path, mode) bind(C) +import c_char, c_ptr + +character(kind=c_char), intent(in) :: path(*), mode(*) +end function gzopen +end interface + +interface +integer(c_int) function gzwrite(file, buf, len) bind(C) +import c_int, c_ptr, c_char + +type(c_ptr), value, intent(in) :: file +character(kind=c_char), intent(in) :: buf +integer(c_int), value, intent(in) :: len +end function gzwrite +end interface + +interface +integer(c_int) function gzclose(file) bind(C) +import c_int, c_ptr + +type(c_ptr), value, intent(in) :: file +end function gzclose +end interface + +end module gzip diff --git a/test cases/fortran/10 find library/main.f90 b/test cases/fortran/10 find library/main.f90 new file mode 100644 index 0000000..e885d30 --- /dev/null +++ b/test cases/fortran/10 find library/main.f90 @@ -0,0 +1,38 @@ +program main +use iso_fortran_env, only: stderr=>error_unit +use iso_c_binding, only: c_int, c_char, c_null_char, c_ptr +use gzip, only: gzopen, gzwrite, gzclose + +implicit none + +character(kind=c_char,len=*), parameter :: path = c_char_"test.gz"//c_null_char +character(kind=c_char,len=*), parameter :: mode = c_char_"wb9"//c_null_char +integer(c_int), parameter :: buffer_size = 512 + +type(c_ptr) :: file +character(kind=c_char, len=buffer_size) :: buffer +integer(c_int) :: ret +integer :: i + +! open file +file = gzopen(path, mode) + +! fill buffer with data +do i=1,buffer_size/4 + write(buffer(4*(i-1)+1:4*i), '(i3.3, a)') i, new_line('') +end do +ret = gzwrite(file, buffer, buffer_size) +if (ret /= buffer_size) then + write(stderr,'(a, i3, a, i3, a)') 'Error: ', ret, ' / ', buffer_size, & + ' bytes written.' + stop 1 +end if + +! close file +ret = gzclose(file) +if (ret /= 0) then + write(stderr,*) 'Error: failure to close file with error code ', ret + stop 1 +end if + +end program diff --git a/test cases/fortran/10 find library/meson.build b/test cases/fortran/10 find library/meson.build new file mode 100644 index 0000000..2a2ef31 --- /dev/null +++ b/test cases/fortran/10 find library/meson.build @@ -0,0 +1,13 @@ +project('find fortran library', 'fortran') + +fc = meson.get_compiler('fortran') + +sources = ['main.f90', 'gzip.f90'] +zlib = fc.find_library('z', required: false) + +if not zlib.found() + error('MESON_SKIP_TEST: Z library not available.') +endif + +exe = executable('zlibtest', sources, dependencies : zlib) +test('testzlib', exe) diff --git a/test cases/fortran/11 compiles links runs/meson.build b/test cases/fortran/11 compiles links runs/meson.build new file mode 100644 index 0000000..150c1a4 --- /dev/null +++ b/test cases/fortran/11 compiles links runs/meson.build @@ -0,0 +1,17 @@ +project('compiles_links_runs', 'fortran') + +fc = meson.get_compiler('fortran') + +code = '''error stop 123; end''' + +if not fc.compiles(code) + error('Fortran 2008 code failed to compile') +endif + +if not fc.links(code) + error('Fortran 2008 code failed to link') +endif + +if fc.run(code).returncode() != 123 + error('Fortran 2008 code failed to run') +endif diff --git a/test cases/fortran/12 submodule/a1.f90 b/test cases/fortran/12 submodule/a1.f90 new file mode 100644 index 0000000..c4b4555 --- /dev/null +++ b/test cases/fortran/12 submodule/a1.f90 @@ -0,0 +1,26 @@ +module a1 +implicit none + +interface +module elemental real function pi2tau(pi) + real, intent(in) :: pi +end function pi2tau + +module real function get_pi() +end function get_pi +end interface + +end module a1 + +program hierN + +use a1 +real :: tau, pi + +pi = get_pi() + +tau = pi2tau(pi) + +print *,'pi=',pi,'tau=',tau + +end program diff --git a/test cases/fortran/12 submodule/a2.f90 b/test cases/fortran/12 submodule/a2.f90 new file mode 100644 index 0000000..ba8a0dd --- /dev/null +++ b/test cases/fortran/12 submodule/a2.f90 @@ -0,0 +1,10 @@ +! testing no space between submodule() +submodule(a1) a2 + +contains + +module procedure pi2tau + pi2tau = 2*pi +end procedure pi2tau + +end submodule a2 diff --git a/test cases/fortran/12 submodule/a3.f90 b/test cases/fortran/12 submodule/a3.f90 new file mode 100644 index 0000000..3881675 --- /dev/null +++ b/test cases/fortran/12 submodule/a3.f90 @@ -0,0 +1,13 @@ +! submodule (bogus) foo +! testing don't detect commented submodule + +submodule (a1:a2) a3 ! testing inline comment + +contains + +module procedure get_pi + get_pi = 4.*atan(1.) +end procedure get_pi + + +end submodule a3 diff --git a/test cases/fortran/12 submodule/child.f90 b/test cases/fortran/12 submodule/child.f90 new file mode 100644 index 0000000..baf1fef --- /dev/null +++ b/test cases/fortran/12 submodule/child.f90 @@ -0,0 +1,13 @@ +submodule (parent) child + +contains + +module procedure pi2tau + pi2tau = 2*pi +end procedure pi2tau + +module procedure good +print *, 'Good!' +end procedure good + +end submodule child diff --git a/test cases/fortran/12 submodule/meson.build b/test cases/fortran/12 submodule/meson.build new file mode 100644 index 0000000..204a36b --- /dev/null +++ b/test cases/fortran/12 submodule/meson.build @@ -0,0 +1,13 @@ +project('submodule single level', 'fortran', + meson_version: '>= 0.50.0') + +fortc = meson.get_compiler('fortran') +if fortc.get_id() == 'gcc' and fortc.version().version_compare('<6.0') + error('MESON_SKIP_TEST need gfortran >= 6.0 for submodule support') +endif + +hier2 = executable('single', 'parent.f90', 'child.f90') +test('single-level hierarchy', hier2) + +hierN = executable('multi', 'a1.f90', 'a2.f90', 'a3.f90') +test('multi-level hierarchy', hierN) diff --git a/test cases/fortran/12 submodule/parent.f90 b/test cases/fortran/12 submodule/parent.f90 new file mode 100644 index 0000000..efc7cf6 --- /dev/null +++ b/test cases/fortran/12 submodule/parent.f90 @@ -0,0 +1,26 @@ +module parent +real, parameter :: pi = 4.*atan(1.) +real :: tau + +interface +module elemental real function pi2tau(pi) + real, intent(in) :: pi +end function pi2tau + +module subroutine good() +end subroutine good +end interface + +end module parent + +program main + +use parent + +tau = pi2tau(pi) + +print *,'pi=',pi, 'tau=', tau + +call good() + +end program diff --git a/test cases/fortran/13 coarray/main.f90 b/test cases/fortran/13 coarray/main.f90 new file mode 100644 index 0000000..eee03ea --- /dev/null +++ b/test cases/fortran/13 coarray/main.f90 @@ -0,0 +1,10 @@ +program main +implicit none + +if (this_image() == 1) print *, 'number of Fortran coarray images:', num_images() + +sync all ! semaphore, ensures message above is printed at top. + +print *, 'Process ', this_image() + +end program diff --git a/test cases/fortran/13 coarray/meson.build b/test cases/fortran/13 coarray/meson.build new file mode 100644 index 0000000..893cec9 --- /dev/null +++ b/test cases/fortran/13 coarray/meson.build @@ -0,0 +1,24 @@ +project('Fortran coarray', 'fortran', + meson_version: '>=0.50') + +fc = meson.get_compiler('fortran') + +if ['pgi', 'flang'].contains(fc.get_id()) + error('MESON_SKIP_TEST: At least through PGI 19.10 and Flang 7.1 do not support Fortran Coarrays.') +endif + +# coarray is required because single-image fallback is an intrinsic feature +coarray = dependency('coarray') + +# check coarray, because user might not have all the library stack installed correctly +# for example, conflicting library/compiler versions on PATH +# this has to invoke a run of "sync all" to verify the MPI stack is functioning, +# particularly for dynamic linking +if fc.run('sync all; end', dependencies: coarray, name: 'Coarray link & run').returncode() != 0 + error('MESON_SKIP_TEST: coarray stack (including MPI) did not link correctly so that a simple test could run.') +endif + +exe = executable('hello', 'main.f90', + dependencies : coarray) + +test('Coarray hello world', exe, timeout: 10) diff --git a/test cases/fortran/14 fortran links c/clib.c b/test cases/fortran/14 fortran links c/clib.c new file mode 100644 index 0000000..81b2e0c --- /dev/null +++ b/test cases/fortran/14 fortran links c/clib.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +void hello(void){ + + printf("hello from C\n"); + +} diff --git a/test cases/fortran/14 fortran links c/clib.def b/test cases/fortran/14 fortran links c/clib.def new file mode 100644 index 0000000..4caeb24 --- /dev/null +++ b/test cases/fortran/14 fortran links c/clib.def @@ -0,0 +1,2 @@ +EXPORTS + hello diff --git a/test cases/fortran/14 fortran links c/f_call_c.f90 b/test cases/fortran/14 fortran links c/f_call_c.f90 new file mode 100644 index 0000000..b3f70a7 --- /dev/null +++ b/test cases/fortran/14 fortran links c/f_call_c.f90 @@ -0,0 +1,11 @@ +program main +implicit none + +interface +subroutine hello() bind (c) +end subroutine hello +end interface + +call hello() + +end program diff --git a/test cases/fortran/14 fortran links c/meson.build b/test cases/fortran/14 fortran links c/meson.build new file mode 100644 index 0000000..380a85a --- /dev/null +++ b/test cases/fortran/14 fortran links c/meson.build @@ -0,0 +1,17 @@ +project('Fortran calling C', 'fortran', 'c', + meson_version: '>= 0.51.0', + default_options : ['default_library=static']) + +ccid = meson.get_compiler('c').get_id() +fcid = meson.get_compiler('fortran').get_id() + +if fcid == 'gcc' and ccid in ['msvc', 'clang-cl'] + error('MESON_SKIP_TEST: MSVC and GCC do not interoperate like this.') +endif + +c_lib = library('clib', 'clib.c', vs_module_defs : 'clib.def') + +f_call_c = executable('f_call_c', 'f_call_c.f90', + link_with: c_lib, + link_language: 'fortran') +test('Fortran calling C', f_call_c) diff --git a/test cases/fortran/15 include/inc1.f90 b/test cases/fortran/15 include/inc1.f90 new file mode 100644 index 0000000..163f586 --- /dev/null +++ b/test cases/fortran/15 include/inc1.f90 @@ -0,0 +1,5 @@ + +real :: pi = 4.*atan(1.) +real :: tau + +include "inc2.f90" ! testing inline comment diff --git a/test cases/fortran/15 include/inc2.f90 b/test cases/fortran/15 include/inc2.f90 new file mode 100644 index 0000000..065b990 --- /dev/null +++ b/test cases/fortran/15 include/inc2.f90 @@ -0,0 +1,2 @@ + +tau = 2*pi diff --git a/test cases/fortran/15 include/include_hierarchy.f90 b/test cases/fortran/15 include/include_hierarchy.f90 new file mode 100644 index 0000000..0598d87 --- /dev/null +++ b/test cases/fortran/15 include/include_hierarchy.f90 @@ -0,0 +1,9 @@ +program test_include_hier + +implicit none + +include "inc1.f90" + +print *, '2*pi:', tau + +end program diff --git a/test cases/fortran/15 include/include_syntax.f90 b/test cases/fortran/15 include/include_syntax.f90 new file mode 100644 index 0000000..5f7eb9f --- /dev/null +++ b/test cases/fortran/15 include/include_syntax.f90 @@ -0,0 +1,25 @@ +program test_include_syntax + +implicit none + +integer :: x, y + +x = 1 +y = 0 + +! include "timestwo.f90" + +include "timestwo.f90" ! inline comment check +if (x/=2) error stop 'failed on first include' + +! leading space check + include 'timestwo.f90' +if (x/=4) error stop 'failed on second include' + +! Most Fortran compilers can't handle the non-standard #include, +! including (ha!) Flang, Gfortran, Ifort and PGI. +! #include "timestwo.f90" + +print *, 'OK: Fortran include tests: x=',x + +end program diff --git a/test cases/fortran/15 include/meson.build b/test cases/fortran/15 include/meson.build new file mode 100644 index 0000000..e19c47f --- /dev/null +++ b/test cases/fortran/15 include/meson.build @@ -0,0 +1,19 @@ +project('Inclusive', 'fortran', + meson_version: '>= 0.51.1') + +cm = import('cmake') + +hier_exe = executable('include_hierarchy', 'include_hierarchy.f90') +test('Fortran include file hierarchy', hier_exe) + +syntax_exe = executable('include_syntax', 'include_syntax.f90') +test('Fortran include file syntax', syntax_exe) + +# older CI runs into problems with too-old Ninja and CMake and Fortran +ninja_version = run_command('ninja', '--version', check: true).stdout().strip() +cmake_version = run_command('cmake', '--version', check: true).stdout().split()[2] +if ninja_version.version_compare('>=1.10.0') and cmake_version.version_compare('>=3.17.0') + cm.subproject('cmake_inc') +else + message('SKIP: CMake Fortran subproject with include. Ninja >= 1.10 and CMake >= 3.17 needed. You have Ninja ' + ninja_version + ' and CMake ' + cmake_version) +endif diff --git a/test cases/fortran/15 include/subprojects/cmake_inc/CMakeLists.txt b/test cases/fortran/15 include/subprojects/cmake_inc/CMakeLists.txt new file mode 100644 index 0000000..1ffe882 --- /dev/null +++ b/test cases/fortran/15 include/subprojects/cmake_inc/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.17) +project(cmake_inc LANGUAGES Fortran) + +add_executable(main main.f90) diff --git a/test cases/fortran/15 include/subprojects/cmake_inc/main.f90 b/test cases/fortran/15 include/subprojects/cmake_inc/main.f90 new file mode 100644 index 0000000..dd2991d --- /dev/null +++ b/test cases/fortran/15 include/subprojects/cmake_inc/main.f90 @@ -0,0 +1,9 @@ +program test_subproject_inc + +implicit none + +include 'thousand.f90' + +if (thousand /= 1000) error stop 'did not include properly' + +end program diff --git a/test cases/fortran/15 include/subprojects/cmake_inc/thousand.f90 b/test cases/fortran/15 include/subprojects/cmake_inc/thousand.f90 new file mode 100644 index 0000000..08a4048 --- /dev/null +++ b/test cases/fortran/15 include/subprojects/cmake_inc/thousand.f90 @@ -0,0 +1 @@ +integer, parameter :: thousand = 1000 diff --git a/test cases/fortran/15 include/timestwo.f90 b/test cases/fortran/15 include/timestwo.f90 new file mode 100644 index 0000000..0e2d5ac --- /dev/null +++ b/test cases/fortran/15 include/timestwo.f90 @@ -0,0 +1,2 @@ +x = 2*x +y = y+1
\ No newline at end of file diff --git a/test cases/fortran/16 openmp/main.f90 b/test cases/fortran/16 openmp/main.f90 new file mode 100644 index 0000000..26b792f --- /dev/null +++ b/test cases/fortran/16 openmp/main.f90 @@ -0,0 +1,18 @@ +program main +use, intrinsic :: iso_fortran_env, only: stderr=>error_unit +use omp_lib, only: omp_get_max_threads +implicit none + +integer :: N, ierr +character(80) :: buf ! can't be allocatable in this use case. Just set arbitrarily large. + +call get_environment_variable('OMP_NUM_THREADS', buf, status=ierr) +if (ierr/=0) error stop 'environment variable OMP_NUM_THREADS could not be read' +read(buf,*) N + +if (omp_get_max_threads() /= N) then + write(stderr, *) 'Max Fortran threads: ', omp_get_max_threads(), '!=', N + error stop +endif + +end program diff --git a/test cases/fortran/16 openmp/meson.build b/test cases/fortran/16 openmp/meson.build new file mode 100644 index 0000000..f021ce2 --- /dev/null +++ b/test cases/fortran/16 openmp/meson.build @@ -0,0 +1,34 @@ +# This test is complementary to and extends "common/190 openmp" so that +# we can examine more compilers and options than would be warranted in +# the common test where C/C++ must also be handled. +project('openmp', 'fortran', + meson_version: '>= 0.46') + + +fc = meson.get_compiler('fortran') +if fc.get_id() == 'gcc' and fc.version().version_compare('<4.2.0') + error('MESON_SKIP_TEST gcc is too old to support OpenMP.') +endif +if host_machine.system() == 'darwin' + error('MESON_SKIP_TEST macOS does not support OpenMP.') +endif + +openmp = dependency('openmp') + +env = environment() +env.set('OMP_NUM_THREADS', '2') + +exef = executable('exef', + 'main.f90', + dependencies : [openmp]) +test('OpenMP Fortran', exef, env : env) + +openmp_f = dependency('openmp', language : 'fortran') +exe_f = executable('exe_f', + 'main.f90', + dependencies : [openmp_f]) +test('OpenMP Fortran-specific', exe_f, env : env) + + +# Check we can apply a version constraint +dependency('openmp', version: '>=@0@'.format(openmp.version())) diff --git a/test cases/fortran/17 add_languages/meson.build b/test cases/fortran/17 add_languages/meson.build new file mode 100644 index 0000000..e7de180 --- /dev/null +++ b/test cases/fortran/17 add_languages/meson.build @@ -0,0 +1,5 @@ +project('add_lang_fortran') + +# catch bug where Fortran compiler is found with project('foo', 'fortran') but +# not by add_languages('fortran') +assert(add_languages('fortran'), 'these tests assume Fortran compiler can be found')
\ No newline at end of file diff --git a/test cases/fortran/18 first_arg/main.f90 b/test cases/fortran/18 first_arg/main.f90 new file mode 100644 index 0000000..6ea28b1 --- /dev/null +++ b/test cases/fortran/18 first_arg/main.f90 @@ -0,0 +1,3 @@ +program main +i = 3 +end program diff --git a/test cases/fortran/18 first_arg/meson.build b/test cases/fortran/18 first_arg/meson.build new file mode 100644 index 0000000..63021f2 --- /dev/null +++ b/test cases/fortran/18 first_arg/meson.build @@ -0,0 +1,46 @@ +project('fortran_args', 'fortran') + +fc = meson.get_compiler('fortran') + +if fc.get_id() == 'intel-cl' + is_arg = '/O2' + useless = '/DFOO' +else + is_arg = '-O2' + useless = '-DFOO' +endif + +isnt_arg = '-fiambroken' + +assert(fc.has_argument(is_arg), 'Arg that should have worked does not work.') +assert(not fc.has_argument(isnt_arg), 'Arg that should be broken is not.') + +assert(fc.get_supported_arguments([is_arg, isnt_arg, useless]) == [is_arg, useless], 'Arg filtering returned different result.') + +# Have useless at the end to ensure that the search goes from front to back. +l1 = fc.first_supported_argument([isnt_arg, is_arg, isnt_arg, useless]) +l2 = fc.first_supported_argument(isnt_arg, isnt_arg, isnt_arg) + +assert(l1.length() == 1, 'First supported returned wrong result.') +assert(l1.get(0) == is_arg, 'First supported returned wrong argument.') +assert(l2.length() == 0, 'First supported did not return empty array.') + +# --- test with an actual program, here for implicit none + +in0 = fc.first_supported_argument('-fimplicit-none', '-Mdclchk', '/warn:declarations', '-warn').get(0, '') +impnone = { +'intel-cl': '/warn:declarations', +'intel': '-warn', +'gcc': '-fimplicit-none', +'pgi': '-Mdclchk', +} + +arg = impnone.get(fc.get_id(), '') +if arg != '' + assert(in0 == arg, 'implicit none argument ' + arg + ' not matching ' + in0) +endif + +in1 = fc.get_supported_arguments('-fimplicit-none', '/warn:declarations', '/warn:errors', '-Mdclchk') +if in1.length() > 0 + assert(not fc.compiles(files('main.f90'), args: in1, name:'will fail implicit none'), 'implicit none should have failed') +endif 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..014bcc1 --- /dev/null +++ b/test cases/fortran/19 fortran_std/legacy.f @@ -0,0 +1,8 @@ + program main + ! non-integer loop indices are deleted in Fortran 95 standard + real a + + do 10 a=0,0.5,0.1 +10 continue + + end program 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..0382192 --- /dev/null +++ b/test cases/fortran/19 fortran_std/std2003.f90 @@ -0,0 +1,37 @@ +program main +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 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..750173e --- /dev/null +++ b/test cases/fortran/19 fortran_std/std2008.f90 @@ -0,0 +1,33 @@ +program main +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 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..34fad50 --- /dev/null +++ b/test cases/fortran/19 fortran_std/std2018.f90 @@ -0,0 +1,35 @@ +program main +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 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..2837da8 --- /dev/null +++ b/test cases/fortran/19 fortran_std/std95.f90 @@ -0,0 +1,14 @@ +program main +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 diff --git a/test cases/fortran/2 modules/comment_mod.f90 b/test cases/fortran/2 modules/comment_mod.f90 new file mode 100644 index 0000000..917f6be --- /dev/null +++ b/test cases/fortran/2 modules/comment_mod.f90 @@ -0,0 +1,6 @@ +module line ! inline comment +implicit none + +real :: length + +end module line diff --git a/test cases/fortran/2 modules/meson.build b/test cases/fortran/2 modules/meson.build new file mode 100644 index 0000000..c9bfd8d --- /dev/null +++ b/test cases/fortran/2 modules/meson.build @@ -0,0 +1,9 @@ +project('modules', 'fortran', + default_options : ['default_library=static']) + +commented = library('commented', 'comment_mod.f90') + +# Have one file with an upper case file extension. +e = executable('modprog', 'mymod.F90', 'prog.f90', + link_with: commented) +test('moduletest', e) diff --git a/test cases/fortran/2 modules/mymod.F90 b/test cases/fortran/2 modules/mymod.F90 new file mode 100644 index 0000000..a45f5c9 --- /dev/null +++ b/test cases/fortran/2 modules/mymod.F90 @@ -0,0 +1,8 @@ +! module circle to be sure module regex doesn't allow commented modules + +module circle +implicit none + +real, parameter :: pi = 4.*atan(1.) +real :: radius +end module circle diff --git a/test cases/fortran/2 modules/prog.f90 b/test cases/fortran/2 modules/prog.f90 new file mode 100644 index 0000000..ef72d11 --- /dev/null +++ b/test cases/fortran/2 modules/prog.f90 @@ -0,0 +1,11 @@ +program main +use circle, only: pi +use line, only: length +implicit none + +print *,'pi=',pi + +length = pi +print *, length + +end program diff --git a/test cases/fortran/20 buildtype/main.f90 b/test cases/fortran/20 buildtype/main.f90 new file mode 100644 index 0000000..ecc7d61 --- /dev/null +++ b/test cases/fortran/20 buildtype/main.f90 @@ -0,0 +1,2 @@ +program main +end program diff --git a/test cases/fortran/20 buildtype/meson.build b/test cases/fortran/20 buildtype/meson.build new file mode 100644 index 0000000..2be6337 --- /dev/null +++ b/test cases/fortran/20 buildtype/meson.build @@ -0,0 +1,5 @@ +# checks for unexpected behavior on non-default buildtype and warning_level +project('build type Fortran', 'fortran', + default_options: ['buildtype=release', 'warning_level=3']) + +executable('main', 'main.f90') diff --git a/test cases/fortran/21 install static/main.f90 b/test cases/fortran/21 install static/main.f90 new file mode 100644 index 0000000..d0c67fe --- /dev/null +++ b/test cases/fortran/21 install static/main.f90 @@ -0,0 +1,5 @@ +program main +use main_lib +implicit none +call main_hello() +end program diff --git a/test cases/fortran/21 install static/main_lib.f90 b/test cases/fortran/21 install static/main_lib.f90 new file mode 100644 index 0000000..874584d --- /dev/null +++ b/test cases/fortran/21 install static/main_lib.f90 @@ -0,0 +1,16 @@ +module main_lib + + use static_hello + implicit none + + private + public :: main_hello + + contains + + subroutine main_hello + call static_say_hello() + print *, "Main hello routine finished." + end subroutine main_hello + +end module main_lib diff --git a/test cases/fortran/21 install static/meson.build b/test cases/fortran/21 install static/meson.build new file mode 100644 index 0000000..b4d3e40 --- /dev/null +++ b/test cases/fortran/21 install static/meson.build @@ -0,0 +1,20 @@ +# Based on 'fortran/5 static', but: +# - Uses a subproject dependency +# - Is an install:true static library to trigger certain codepath (promotion to link_whole) +# - Does fortran code 'generation' with configure_file +# - Uses .F90 ext (capital F typically denotes a dependence on preprocessor treatment, which however is not used) +project('try-static-subproject-dependency', 'fortran') + +static_dep = dependency('static_hello', fallback: ['static_hello', 'static_hello_dep']) + +mainsrc = 'main_lib.f90' +mainsrc = configure_file( + copy: true, + input: mainsrc, + output: 'main_lib_output.F90' +) +main_lib = library('mainstatic', mainsrc, dependencies: static_dep, install: true) +main_dep = declare_dependency(link_with: main_lib) + +main_exe = executable('main_exe', 'main.f90', dependencies: main_dep) +test('static_subproject_test', main_exe) diff --git a/test cases/fortran/21 install static/subprojects/static_hello/meson.build b/test cases/fortran/21 install static/subprojects/static_hello/meson.build new file mode 100644 index 0000000..5e13bae --- /dev/null +++ b/test cases/fortran/21 install static/subprojects/static_hello/meson.build @@ -0,0 +1,12 @@ +project('static-hello', 'fortran') + +# staticlibsource = 'static_hello.f90' +staticlibsource = configure_file( + copy: true, + input: 'static_hello.f90', + output: 'static_hello_output.F90' +) + +static_hello_lib = static_library('static_hello', staticlibsource, install: false) + +static_hello_dep = declare_dependency(link_with: static_hello_lib) diff --git a/test cases/fortran/21 install static/subprojects/static_hello/static_hello.f90 b/test cases/fortran/21 install static/subprojects/static_hello/static_hello.f90 new file mode 100644 index 0000000..5407560 --- /dev/null +++ b/test cases/fortran/21 install static/subprojects/static_hello/static_hello.f90 @@ -0,0 +1,17 @@ +module static_hello +implicit none + +private +public :: static_say_hello + +interface static_say_hello + module procedure say_hello +end interface static_say_hello + +contains + +subroutine say_hello + print *, "Static library called." +end subroutine say_hello + +end module static_hello diff --git a/test cases/fortran/21 install static/test.json b/test cases/fortran/21 install static/test.json new file mode 100644 index 0000000..aff7147 --- /dev/null +++ b/test cases/fortran/21 install static/test.json @@ -0,0 +1,10 @@ +{ + "installed": [ + {"file": "usr/lib/libmainstatic.a", "type": "file"} + ], + "matrix": { + "options": { + "default_library": [ { "val": "static" } ] + } + } +} diff --git a/test cases/fortran/3 module procedure/meson.build b/test cases/fortran/3 module procedure/meson.build new file mode 100644 index 0000000..a590015 --- /dev/null +++ b/test cases/fortran/3 module procedure/meson.build @@ -0,0 +1,5 @@ +project('Fortran 2003 use statement, in same file', 'fortran', + meson_version: '>= 0.50.0') + +e = executable('use_syntax', 'use_syntax.f90') +test('Fortran 2003 use syntax', e) diff --git a/test cases/fortran/3 module procedure/use_syntax.f90 b/test cases/fortran/3 module procedure/use_syntax.f90 new file mode 100644 index 0000000..2f3a9e6 --- /dev/null +++ b/test cases/fortran/3 module procedure/use_syntax.f90 @@ -0,0 +1,31 @@ +module circle +implicit none + +integer :: x +real :: radius + +interface default + module procedure timestwo +end interface + +contains + +elemental integer function timestwo(x) result(y) + integer, intent(in) :: x + y = 2*x +end function +end module circle + +program prog + +use, non_intrinsic :: circle, only: timestwo, x + +implicit none + +x = 3 + +if (timestwo(x) /= 6) error stop 'fortran module procedure problem' + +print *,'OK: Fortran module procedure' + +end program prog diff --git a/test cases/fortran/4 self dependency/meson.build b/test cases/fortran/4 self dependency/meson.build new file mode 100644 index 0000000..e791284 --- /dev/null +++ b/test cases/fortran/4 self dependency/meson.build @@ -0,0 +1,8 @@ +project('selfdep', 'fortran') + +e = executable('selfdep', 'selfdep.f90') +test('selfdep', e) + +library('selfmod', 'src/selfdep_mod.f90') + +subproject('sub1') diff --git a/test cases/fortran/4 self dependency/selfdep.f90 b/test cases/fortran/4 self dependency/selfdep.f90 new file mode 100644 index 0000000..1a71353 --- /dev/null +++ b/test cases/fortran/4 self dependency/selfdep.f90 @@ -0,0 +1,18 @@ +MODULE geom + +type :: circle + REAL :: Pi = 4.*atan(1.) + REAL :: radius +end type circle +END MODULE geom + +PROGRAM prog + +use geom, only : circle +IMPLICIT NONE + +type(circle) :: ell + +ell%radius = 3. + +END PROGRAM prog diff --git a/test cases/fortran/4 self dependency/src/selfdep_mod.f90 b/test cases/fortran/4 self dependency/src/selfdep_mod.f90 new file mode 100644 index 0000000..4aa0057 --- /dev/null +++ b/test cases/fortran/4 self dependency/src/selfdep_mod.f90 @@ -0,0 +1,6 @@ +module a +end module a + +module b +use a +end module b diff --git a/test cases/fortran/4 self dependency/subprojects/sub1/main.f90 b/test cases/fortran/4 self dependency/subprojects/sub1/main.f90 new file mode 100644 index 0000000..873427d --- /dev/null +++ b/test cases/fortran/4 self dependency/subprojects/sub1/main.f90 @@ -0,0 +1,6 @@ +module a +end + +program b + use a +end diff --git a/test cases/fortran/4 self dependency/subprojects/sub1/meson.build b/test cases/fortran/4 self dependency/subprojects/sub1/meson.build new file mode 100644 index 0000000..606f338 --- /dev/null +++ b/test cases/fortran/4 self dependency/subprojects/sub1/meson.build @@ -0,0 +1,3 @@ +project('subproject self-def', 'fortran') + +library('subself', 'main.f90') diff --git a/test cases/fortran/5 static/main.f90 b/test cases/fortran/5 static/main.f90 new file mode 100644 index 0000000..4db2861 --- /dev/null +++ b/test cases/fortran/5 static/main.f90 @@ -0,0 +1,6 @@ +program main +use static_hello +implicit none + +call static_say_hello() +end program diff --git a/test cases/fortran/5 static/meson.build b/test cases/fortran/5 static/meson.build new file mode 100644 index 0000000..ab9d3c4 --- /dev/null +++ b/test cases/fortran/5 static/meson.build @@ -0,0 +1,6 @@ +project('try-static-library', 'fortran') + +static_hello = static_library('static_hello', 'static_hello.f90') + +exe = executable('test_exe', 'main.f90', link_with : static_hello) +test('static-fortran', exe) diff --git a/test cases/fortran/5 static/static_hello.f90 b/test cases/fortran/5 static/static_hello.f90 new file mode 100644 index 0000000..5407560 --- /dev/null +++ b/test cases/fortran/5 static/static_hello.f90 @@ -0,0 +1,17 @@ +module static_hello +implicit none + +private +public :: static_say_hello + +interface static_say_hello + module procedure say_hello +end interface static_say_hello + +contains + +subroutine say_hello + print *, "Static library called." +end subroutine say_hello + +end module static_hello diff --git a/test cases/fortran/6 dynamic/dynamic.f90 b/test cases/fortran/6 dynamic/dynamic.f90 new file mode 100644 index 0000000..6a1f359 --- /dev/null +++ b/test cases/fortran/6 dynamic/dynamic.f90 @@ -0,0 +1,17 @@ +module dynamic +implicit none + +private +public :: hello + +interface hello + module procedure say +end interface hello + +contains + +subroutine say + print *, "Hello from shared library." +end subroutine say + +end module dynamic diff --git a/test cases/fortran/6 dynamic/main.f90 b/test cases/fortran/6 dynamic/main.f90 new file mode 100644 index 0000000..ba2e2d2 --- /dev/null +++ b/test cases/fortran/6 dynamic/main.f90 @@ -0,0 +1,6 @@ +program main +use dynamic, only: hello +implicit none + +call hello() +end program diff --git a/test cases/fortran/6 dynamic/meson.build b/test cases/fortran/6 dynamic/meson.build new file mode 100644 index 0000000..413223b --- /dev/null +++ b/test cases/fortran/6 dynamic/meson.build @@ -0,0 +1,13 @@ +project('dynamic_fortran', 'fortran') + +fcid = meson.get_compiler('fortran').get_id() +if fcid == 'intel-cl' or (host_machine.system() == 'windows' and fcid == 'pgi') + error('MESON_SKIP_TEST: non-Gfortran Windows Fortran compilers do not do shared libraries in a Fortran standard way') + # !DEC$ ATTRIBUTES DLLEXPORT must be used! + # https://software.intel.com/en-us/node/535306 + # https://www.pgroup.com/resources/docs/19.4/x86/pgi-user-guide/index.htm#lib-dynlnk-bld-dll-fort +endif + +dynamic = shared_library('dynamic', 'dynamic.f90') +exe = executable('test_exe', 'main.f90', link_with : dynamic) +test('dynamic-fortran', exe) diff --git a/test cases/fortran/7 generated/meson.build b/test cases/fortran/7 generated/meson.build new file mode 100644 index 0000000..f021309 --- /dev/null +++ b/test cases/fortran/7 generated/meson.build @@ -0,0 +1,39 @@ +# Tests whether fortran sources files created during configuration are properly +# scanned for dependency information + +project('generated', 'fortran', + default_options : ['default_library=static']) + +conf_data = configuration_data() +conf_data.set('ONE', 1) +conf_data.set('TWO', 2) + +mod3_f = custom_target( + 'mod3.f', + input : 'mod3.f90', + output : 'mod3.f90', + # We need a platform agnostic way to do a copy a file, using a custom_target + # and we need to use the @OUTDIR@, not @OUTPUT@ in order to exercise + # https://github.com/mesonbuild/meson/issues/9258 + command : [ + find_program('python', 'python3'), '-c', + 'import sys, shutil; shutil.copy(sys.argv[1], sys.argv[2])', + '@INPUT@', '@OUTDIR@', + ], +) + +three = library('mod3', mod3_f) + +templates_basenames = ['mod2', 'mod1'] +generated_sources = [] +foreach template_basename : templates_basenames + infilename = '@0@.fpp'.format(template_basename) + outfilename = '@0@.f90'.format(template_basename) + outfile = configure_file( + input : infilename, output : outfilename, configuration : conf_data) + generated_sources += [outfile] +endforeach + +sources = ['prog.f90'] + generated_sources +exe = executable('generated', sources, link_with: three) +test('generated', exe) diff --git a/test cases/fortran/7 generated/mod1.fpp b/test cases/fortran/7 generated/mod1.fpp new file mode 100644 index 0000000..c4decf6 --- /dev/null +++ b/test cases/fortran/7 generated/mod1.fpp @@ -0,0 +1,6 @@ +module mod1 +implicit none + +integer, parameter :: modval1 = @ONE@ + +end module mod1 diff --git a/test cases/fortran/7 generated/mod2.fpp b/test cases/fortran/7 generated/mod2.fpp new file mode 100644 index 0000000..78ceae4 --- /dev/null +++ b/test cases/fortran/7 generated/mod2.fpp @@ -0,0 +1,7 @@ +module mod2 +use mod1, only : modval1 +implicit none + +integer, parameter :: modval2 = @TWO@ + +end module mod2 diff --git a/test cases/fortran/7 generated/mod3.f90 b/test cases/fortran/7 generated/mod3.f90 new file mode 100644 index 0000000..5e4b417 --- /dev/null +++ b/test cases/fortran/7 generated/mod3.f90 @@ -0,0 +1,6 @@ +module mod3 +implicit none + +integer, parameter :: modval3 = 3 + +end module mod3 diff --git a/test cases/fortran/7 generated/prog.f90 b/test cases/fortran/7 generated/prog.f90 new file mode 100644 index 0000000..6ee0bca --- /dev/null +++ b/test cases/fortran/7 generated/prog.f90 @@ -0,0 +1,8 @@ +program generated +use mod2, only : modval1, modval2 +use mod3, only : modval3 +implicit none + +if (modval1 + modval2 + modval3 /= 6) error stop + +end program generated diff --git a/test cases/fortran/8 module names/meson.build b/test cases/fortran/8 module names/meson.build new file mode 100644 index 0000000..632c597 --- /dev/null +++ b/test cases/fortran/8 module names/meson.build @@ -0,0 +1,6 @@ +project('mod_name_case', 'fortran') + +sources = ['test.f90', 'mod1.f90', 'mod2.f90'] + +exe = executable('mod_name_case', sources) +test('mod_name_case', exe) diff --git a/test cases/fortran/8 module names/mod1.f90 b/test cases/fortran/8 module names/mod1.f90 new file mode 100644 index 0000000..29cd9f4 --- /dev/null +++ b/test cases/fortran/8 module names/mod1.f90 @@ -0,0 +1,6 @@ +module MyMod1 +implicit none + +integer, parameter :: myModVal1 = 1 + +end module MyMod1 diff --git a/test cases/fortran/8 module names/mod2.f90 b/test cases/fortran/8 module names/mod2.f90 new file mode 100644 index 0000000..2087750 --- /dev/null +++ b/test cases/fortran/8 module names/mod2.f90 @@ -0,0 +1,6 @@ +module mymod2 +implicit none + +integer, parameter :: myModVal2 = 2 + +end module mymod2 diff --git a/test cases/fortran/8 module names/test.f90 b/test cases/fortran/8 module names/test.f90 new file mode 100644 index 0000000..60ff16e --- /dev/null +++ b/test cases/fortran/8 module names/test.f90 @@ -0,0 +1,9 @@ +program main +use mymod1 +use MyMod2 ! test inline comment + +implicit none + +integer, parameter :: testVar = myModVal1 + myModVal2 + +end program diff --git a/test cases/fortran/9 cpp/fortran.f b/test cases/fortran/9 cpp/fortran.f new file mode 100644 index 0000000..255872c --- /dev/null +++ b/test cases/fortran/9 cpp/fortran.f @@ -0,0 +1,11 @@ + function fortran() bind(C) + use, intrinsic :: iso_c_binding, only: dp=>c_double + implicit none + + real(dp) :: r, fortran + + call random_number(r) + + fortran = 2._dp**r + + end function fortran diff --git a/test cases/fortran/9 cpp/main.c b/test cases/fortran/9 cpp/main.c new file mode 100644 index 0000000..c1750ad --- /dev/null +++ b/test cases/fortran/9 cpp/main.c @@ -0,0 +1,8 @@ +#include <stdio.h> + +double fortran(void); + +int main(void) { + printf("FORTRAN gave us this number: %lf.\n", fortran()); + return 0; +} diff --git a/test cases/fortran/9 cpp/main.cpp b/test cases/fortran/9 cpp/main.cpp new file mode 100644 index 0000000..534a23a --- /dev/null +++ b/test cases/fortran/9 cpp/main.cpp @@ -0,0 +1,8 @@ +#include <iostream> + +extern "C" double fortran(); + +int main(void) { + std::cout << "FORTRAN gave us this number: " << fortran() << '\n'; + return 0; +} diff --git a/test cases/fortran/9 cpp/meson.build b/test cases/fortran/9 cpp/meson.build new file mode 100644 index 0000000..2afa864 --- /dev/null +++ b/test cases/fortran/9 cpp/meson.build @@ -0,0 +1,29 @@ +project('C, C++ and Fortran', 'c', 'cpp', 'fortran') + +cpp = meson.get_compiler('cpp') +fc = meson.get_compiler('fortran') + +if build_machine.system() == 'windows' and fc.get_id() == 'gcc' and cpp.get_id() != 'gcc' + error('MESON_SKIP_TEST mixing gfortran with non-GNU C++ does not work.') +endif + +link_with = [] +if fc.get_id() == 'intel' + link_with += fc.find_library('ifport') +endif + +e = executable( + 'cfort', + ['main.c', 'fortran.f'], + dependencies : link_with, +) + +test('C and Fortran', e) + +e2 = executable( + 'cppfort', + ['main.cpp', 'fortran.f'], + dependencies : link_with, +) + +test('C++ and Fortran', e2) |