Index: Fortran/gfortran/regression/analyzer/analyzer.exp
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/analyzer.exp
@@ -0,0 +1,55 @@
+# Copyright (C) 2020-2023 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# .
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gfortran-dg.exp
+load_lib gfortran.exp
+
+# If the analyzer has not been enabled, bail.
+if { ![check_effective_target_analyzer] } {
+ return
+}
+
+global DEFAULT_FFLAGS
+if [info exists DEFAULT_FFLAGS] then {
+ set save_default_fflags $DEFAULT_FFLAGS
+}
+
+# If a testcase doesn't have special options, use these.
+set DEFAULT_FFLAGS "-fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries"
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+
+gfortran_init
+
+gfortran-dg-runtest [lsort \
+ [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "" $DEFAULT_FFLAGS
+
+# All done.
+dg-finish
+
+if [info exists save_default_fflags] {
+ set DEFAULT_FFLAGS $save_default_fflags
+} else {
+ unset DEFAULT_FFLAGS
+}
Index: Fortran/gfortran/regression/analyzer/deferred_character_25.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/deferred_character_25.f90
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! { dg-additional-options "-Wno-analyzer-too-complex" }
+
+! Copy of gfortran.dg/deferred_character_25.f90
+! as a regression test for ICE with -fanalyzer (PR analyzer/93774)
+
+PROGRAM TEST
+ IMPLICIT NONE
+ INTEGER, PARAMETER :: I = 3
+ character (len = i), parameter :: str(5) = ['abc','cde','fgh','ijk','lmn']
+
+ TYPE T
+ CHARACTER(LEN=:), ALLOCATABLE :: C(:)
+ END TYPE T
+ TYPE(T), TARGET :: S
+ CHARACTER (LEN=I), POINTER :: P(:)
+
+ ALLOCATE ( CHARACTER(LEN=I) :: S%C(5) )
+ s%c = str
+
+! This PR uncovered several problems associated with determining the
+! element length and indexing. Test fairly thoroughly!
+ if (SIZE(S%C, 1) .ne. 5) stop 1
+ if (LEN(S%C) .ne. 3) stop 2
+ if (any (s%c .ne. str)) stop 3
+ if (s%c(3) .ne. str(3)) stop 4
+ P => S%C
+ if (SIZE(p, 1) .ne. 5) stop 5
+ if (LEN(p) .ne. 3) stop 6
+ if (any (p .ne. str)) stop 7
+ if (p(5) .ne. str(5)) stop 8
+END PROGRAM TEST
Index: Fortran/gfortran/regression/analyzer/malloc-example.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/malloc-example.f90
@@ -0,0 +1,21 @@
+! Example from GCC documentation
+! { dg-do compile }
+! { dg-additional-options "-fcray-pointer" }
+
+program test_malloc
+ implicit none
+ integer i
+ real*8 x(*), z
+ pointer(ptr_x,x)
+
+ ptr_x = malloc(20*8)
+ do i = 1, 20
+ x(i) = sqrt(1.0d0 / i)
+ end do
+ z = 0
+ do i = 1, 20
+ z = z + x(i)
+ print *, z
+ end do
+ call free(ptr_x)
+end program test_malloc
Index: Fortran/gfortran/regression/analyzer/malloc.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/malloc.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-additional-options "-fcray-pointer -O0" }
+
+subroutine test_ok
+ real*8 x(*)
+ pointer(ptr_x,x)
+
+ ptr_x = malloc(20*8)
+ call free(ptr_x)
+end subroutine test_ok ! { dg-bogus "leak" }
+
+subroutine test_double_free
+ real*8 x(*)
+ pointer(ptr_x,x)
+
+ ptr_x = malloc(20*8)
+ call free(ptr_x)
+ call free(ptr_x) ! { dg-warning "double-'free'" }
+end subroutine test_double_free ! { dg-bogus "leak" }
Index: Fortran/gfortran/regression/analyzer/pr107210.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr107210.f90
@@ -0,0 +1,16 @@
+! { dg-additional-options "-O1" }
+
+subroutine check_int (j)
+ INTEGER(4) :: i, ia(5), ib(5,4), ip, ipa(:)
+ target :: ib
+ POINTER :: ip, ipa
+ logical :: l(5)
+
+ ipa=>ib(2:3,1)
+
+ l = (/ sizeof(i) == 4, sizeof(ia) == 20, sizeof(ib) == 80, &
+ sizeof(ip) == 4, sizeof(ipa) == 8 /)
+
+ if (any(.not.l)) STOP 4
+
+end subroutine check_int
Index: Fortran/gfortran/regression/analyzer/pr108065.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr108065.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! { dg-additional-options "-fcheck=bounds -Wno-analyzer-malloc-leak" }
+! Copy of gfortran.dg/bounds_check_23.f90
+! as a regression test for ICE with -fanalyzer (PR analyzer/108065)
+
+program test
+ implicit none
+ call sub('Lorem ipsum')
+contains
+ subroutine sub( text )
+ character(len=*), intent(in) :: text
+ character(len=1), allocatable :: c(:)
+ integer :: i
+ c = [ ( text(i:i), i = 1, len(text) ) ]
+ if (c(1) /= 'L') stop 1
+ end subroutine sub
+end program test
Index: Fortran/gfortran/regression/analyzer/pr88304-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr88304-2.f90
@@ -0,0 +1,29 @@
+! Copy of gfortran.fortran-torture/compile/pr88304-2.f90
+! as a regression test for ICE with -fanalyzer (PR analyzer/93779)
+
+module pr88304
+ implicit none
+ integer :: p
+contains
+ function foo (x, y, z, w)
+ integer, intent(in) :: x, y
+ character(*), optional, intent(out) :: z
+ integer, optional, intent(out) :: w
+ integer :: foo
+ foo = 1
+ end function foo
+ subroutine bar ()
+ integer :: s
+ s = baz (1)
+ contains
+ function baz (u)
+ integer, intent(in) :: u
+ integer :: baz
+ integer :: q
+ integer :: r (10)
+ r = 0
+ baz = 1
+ q = foo (p, r(u), w = baz)
+ end function baz
+ end subroutine bar
+end module pr88304
Index: Fortran/gfortran/regression/analyzer/pr93405.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr93405.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+real a(10), b(10), c(10)
+a = 0.
+b = 1.
+call sum(a, b, c, 10)
+print *, c(5)
+end
+subroutine sum(a, b, c, n)
+integer i, n
+real a(n), b(n), c(n)
+do i = 1, n
+ c(i) = a(i) + b(i)
+enddo
+end
Index: Fortran/gfortran/regression/analyzer/pr93777.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr93777.f90
@@ -0,0 +1,22 @@
+! { dg-additional-options "-O0 -Wno-analyzer-possible-null-dereference -Wno-analyzer-null-dereference -Wno-analyzer-malloc-leak" }
+
+program cb
+ implicit none
+ type :: jn
+ real, allocatable :: ie
+ character(len = :), allocatable :: e5
+ end type jn
+ real, parameter :: gm = 5.0
+
+ block
+ type(jn) :: r2
+
+ r2 = jn (gm, "")
+ call vz (r2%ie, gm)
+ end block
+contains
+ subroutine vz (arg1, arg2)
+ real :: arg1, arg2
+ if (arg1 .ne. arg2) STOP 1
+ end subroutine vz
+end program cb
Index: Fortran/gfortran/regression/analyzer/pr93778.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr93778.f90
@@ -0,0 +1,11 @@
+program h0
+ type bl
+ integer jq
+ end type bl
+ type qn
+ type (bl), dimension(3) :: xi
+ end type qn
+ type (qn) ro
+ namelist /i2/ ro
+ read(10, nml = i2)
+end program h0
Index: Fortran/gfortran/regression/analyzer/pr93993.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr93993.f90
@@ -0,0 +1,33 @@
+module np
+ implicit none
+ integer, parameter :: za = selected_real_kind(15, 307)
+end module np
+
+module gg
+ use np
+
+ type et(real_kind)
+ integer, kind :: real_kind
+ end type et
+
+contains
+
+ function hv (tm) result(ce)
+ type (et(real_kind=za)), allocatable, target :: tm
+ type (et(real_kind=za)), pointer :: ce
+
+ allocate (tm) ! { dg-bogus "dereference of possibly-NULL" }
+ ce => tm
+ end function hv
+
+end module gg
+
+program a5
+ use np
+ use gg
+ implicit none
+ type (et(real_kind=za)), allocatable :: qb
+ type (et(real_kind=za)), pointer :: vt
+
+ vt => hv (qb)
+end program a5 ! { dg-warning "leak of '.*qb'" }
Index: Fortran/gfortran/regression/analyzer/pr96949.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr96949.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-additional-options "-Wno-analyzer-too-complex --param analyzer-max-svalue-depth=0" }
+
+program n6
+ integer :: ck(2,2)
+ integer :: ac
+
+ data ck /4 * 1/
+
+ call x9()
+
+contains
+ subroutine x9()
+ if (ck(2, 1) == 1) then
+ ac = 1
+ else
+ ac = 0
+ end if
+ end subroutine x9
+end program n6
Index: Fortran/gfortran/regression/analyzer/pr97668.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/pr97668.f
@@ -0,0 +1,26 @@
+c { dg-additional-options "-std=legacy -Wno-analyzer-use-of-uninitialized-value -Wno-analyzer-too-complex" }
+
+ SUBROUTINE PPADD (A, C, BH)
+
+ COMPLEX DD, FP, FPP, R1, R2
+ DIMENSION A(*), C(*), BH(*)
+
+ DO 136 IG=IS,1
+ FP = (0.,0.)
+ FPP = (0.,0.)
+
+ DO 121 J=1,1
+ DD = 1./2
+ FP = DD
+ FPP = DD+1
+ 121 CONTINUE
+
+ R2 = -FP
+ IF (ABS(R1)-ABS(R2)) 129,129,133
+ 129 R1 = R2/FPP
+ 133 IT = IT+1
+
+ 136 CONTINUE
+
+ RETURN
+ END
Index: Fortran/gfortran/regression/analyzer/uninit-pr63311.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/analyzer/uninit-pr63311.f90
@@ -0,0 +1,39 @@
+! { dg-additional-options "-O0" }
+
+MODULE M1
+ IMPLICIT NONE
+CONTAINS
+ INTEGER FUNCTION foo()
+ INTEGER, VOLATILE :: v=42
+ foo=v
+ END FUNCTION
+ SUBROUTINE test(n,flag)
+ INTEGER :: n,i,j,k,l,tt
+ LOGICAL :: flag
+ REAL(KIND=8) :: v,t
+ IF (flag) THEN
+ t=42
+ tt=foo()
+ ENDIF
+ v=0
+ DO i=1,n
+ v=0
+ IF (flag) THEN
+ IF (tt==i) v=MAX(v,t)
+ ENDIF
+ DO j=1,n
+ DO k=1,n
+ v=MAX(v,sin(REAL(j*k)))
+ ENDDO
+ ENDDO
+ ENDDO
+ END SUBROUTINE
+END MODULE M1
+
+USE M1
+INTEGER :: n
+LOGICAL :: flag
+n=4
+flag=.FALSE.
+CALL test(n,flag)
+END
Index: Fortran/gfortran/regression/asan/asan.exp
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/asan/asan.exp
@@ -0,0 +1,40 @@
+# Copyright (C) 2020-2023 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# .
+
+# GCC testsuite for gfortran that checks for -fsanitize=address error.
+
+# Contributed by Thomas König,
+
+# Load support procs.
+load_lib gfortran-dg.exp
+load_lib asan-dg.exp
+
+
+# Initialize `dg'.
+dg-init
+asan_init
+
+# Main loop.
+if [check_effective_target_fsanitize_address] {
+ gfortran-dg-runtest [lsort \
+ [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ] ] "-fsanitize=address" ""
+}
+
+# All done.
+asan_finish
+dg-finish
Index: Fortran/gfortran/regression/asan/associate_58.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/asan/associate_58.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-additional-options "-O0" }
+!
+! PR fortran/104228
+! The code generated code for the program below wrongly pushed the Y character
+! length variable to both P and S scope, which was leading to an ICE when
+! address sanitizer was in effect
+
+program p
+ character(:), save, allocatable :: x(:)
+ call s
+contains
+ subroutine s
+ associate (y => x)
+ y = [x]
+ end associate
+ end
+end
+
Index: Fortran/gfortran/regression/asan/associate_59.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/asan/associate_59.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-additional-options "-O0" }
+!
+! PR fortran/104228
+! The code generated code for the program below wrongly pushed the Y character
+! length variable to both P and S scope, which was leading to an ICE when
+! address sanitizer was in effect
+
+program p
+ character(:), allocatable :: x(:)
+ call s
+contains
+ subroutine s
+ associate (y => x)
+ y = [x]
+ end associate
+ end
+end
+
Index: Fortran/gfortran/regression/asan/pointer_assign_16.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/asan/pointer_assign_16.f90
@@ -0,0 +1,304 @@
+! { dg-do run }
+! PR fortran/94788 - this leads to a double free.
+! Test case by Juergen Reuter.
+module iso_varying_string
+ implicit none
+ integer, parameter, private :: GET_BUFFER_LEN = 1
+ type, public :: varying_string
+ private
+ character(LEN=1), dimension(:), allocatable :: chars
+ end type varying_string
+
+ interface assignment(=)
+ module procedure op_assign_CH_VS
+ module procedure op_assign_VS_CH
+ end interface assignment(=)
+
+ interface char
+ module procedure char_auto
+ module procedure char_fixed
+ end interface char
+
+ interface len
+ module procedure len_
+ end interface len
+
+ interface var_str
+ module procedure var_str_
+ end interface var_str
+
+ public :: assignment(=)
+ public :: char
+ public :: len
+ public :: var_str
+
+ private :: op_assign_CH_VS
+ private :: op_assign_VS_CH
+ private :: op_eq_VS_VS
+ private :: op_eq_CH_VS
+ private :: op_eq_VS_CH
+ private :: char_auto
+ private :: char_fixed
+ private :: len_
+ private :: var_str_
+
+contains
+
+ elemental function len_ (string) result (length)
+ type(varying_string), intent(in) :: string
+ integer :: length
+ if(ALLOCATED(string%chars)) then
+ length = SIZE(string%chars)
+ else
+ length = 0
+ endif
+ end function len_
+
+ elemental subroutine op_assign_CH_VS (var, exp)
+ character(LEN=*), intent(out) :: var
+ type(varying_string), intent(in) :: exp
+ var = char(exp)
+ end subroutine op_assign_CH_VS
+
+ elemental subroutine op_assign_VS_CH (var, exp)
+ type(varying_string), intent(out) :: var
+ character(LEN=*), intent(in) :: exp
+ var = var_str(exp)
+ end subroutine op_assign_VS_CH
+
+ elemental function op_eq_VS_VS (string_a, string_b) result (op_eq)
+ type(varying_string), intent(in) :: string_a
+ type(varying_string), intent(in) :: string_b
+ logical :: op_eq
+ op_eq = char(string_a) == char(string_b)
+ end function op_eq_VS_VS
+
+ elemental function op_eq_CH_VS (string_a, string_b) result (op_eq)
+ character(LEN=*), intent(in) :: string_a
+ type(varying_string), intent(in) :: string_b
+ logical :: op_eq
+ op_eq = string_a == char(string_b)
+ end function op_eq_CH_VS
+
+ elemental function op_eq_VS_CH (string_a, string_b) result (op_eq)
+ type(varying_string), intent(in) :: string_a
+ character(LEN=*), intent(in) :: string_b
+ logical :: op_eq
+ op_eq = char(string_a) == string_b
+ end function op_eq_VS_CH
+
+
+ pure function char_auto (string) result (char_string)
+ type(varying_string), intent(in) :: string
+ character(LEN=len(string)) :: char_string
+ integer :: i_char
+ forall(i_char = 1:len(string))
+ char_string(i_char:i_char) = string%chars(i_char)
+ end forall
+
+ end function char_auto
+
+ pure function char_fixed (string, length) result (char_string)
+ type(varying_string), intent(in) :: string
+ integer, intent(in) :: length
+ character(LEN=length) :: char_string
+ char_string = char(string)
+ end function char_fixed
+
+ elemental function var_str_ (char) result (string)
+ character(LEN=*), intent(in) :: char
+ type(varying_string) :: string
+ integer :: length
+ integer :: i_char
+ length = LEN(char)
+ ALLOCATE(string%chars(length))
+ forall(i_char = 1:length)
+ string%chars(i_char) = char(i_char:i_char)
+ end forall
+ end function var_str_
+
+end module iso_varying_string
+
+
+module parser
+ implicit none
+ private
+ public :: parse_node_t
+ public :: parse_tree_t
+ type :: parse_node_t
+ private
+ end type parse_node_t
+
+ type :: parse_tree_t
+ private
+ type(parse_node_t), pointer :: root_node => null ()
+ contains
+ procedure :: get_root_ptr => parse_tree_get_root_ptr
+ end type parse_tree_t
+
+contains
+ function parse_tree_get_root_ptr (parse_tree) result (node)
+ class(parse_tree_t), intent(in) :: parse_tree
+ type(parse_node_t), pointer :: node
+ node => parse_tree%root_node
+ end function parse_tree_get_root_ptr
+
+end module parser
+
+
+
+module rt_data
+ use iso_varying_string, string_t => varying_string
+ use parser, only: parse_node_t
+ implicit none
+ private
+
+ public :: rt_data_t
+
+ type :: rt_parse_nodes_t
+ type(parse_node_t), pointer :: weight_expr => null ()
+ end type rt_parse_nodes_t
+
+ type :: rt_data_t
+ type(rt_parse_nodes_t) :: pn
+ type(string_t) :: logfile
+ contains
+ procedure :: global_init => rt_data_global_init
+ procedure :: local_init => rt_data_local_init
+ procedure :: activate => rt_data_activate
+ end type rt_data_t
+
+
+contains
+
+ subroutine rt_data_global_init (global, logfile)
+ class(rt_data_t), intent(out), target :: global
+ type(string_t), intent(in), optional :: logfile
+ integer :: seed
+ if (present (logfile)) then
+ global%logfile = logfile
+ else
+ global%logfile = ""
+ end if
+ call system_clock (seed)
+ end subroutine rt_data_global_init
+
+ subroutine rt_data_local_init (local, global, env)
+ class(rt_data_t), intent(inout), target :: local
+ type(rt_data_t), intent(in), target :: global
+ integer, intent(in), optional :: env
+ local%logfile = global%logfile
+ end subroutine rt_data_local_init
+
+ subroutine rt_data_activate (local)
+ class(rt_data_t), intent(inout), target :: local
+ class(rt_data_t), pointer :: global
+
+ ! global => local%context
+ ! if (associated (global)) then
+ ! local%logfile = global%logfile
+ ! local%pn = global%pn
+ ! end if
+ end subroutine rt_data_activate
+
+end module rt_data
+
+module events
+ implicit none
+ private
+ public :: event_t
+
+ type :: event_config_t
+ end type event_config_t
+
+ type :: event_t
+ type(event_config_t) :: config
+ end type event_t
+
+end module events
+
+
+module simulations
+ use iso_varying_string, string_t => varying_string
+ use events
+ use rt_data
+
+ implicit none
+ private
+
+ public :: simulation_t
+
+ type, extends (event_t) :: entry_t
+ private
+ type(entry_t), pointer :: next => null ()
+ end type entry_t
+
+ type, extends (entry_t) :: alt_entry_t
+ contains
+ procedure :: init_alt => alt_entry_init
+ end type alt_entry_t
+
+ type :: simulation_t
+ private
+ type(rt_data_t), pointer :: local => null ()
+ integer :: n_alt = 0
+ type(entry_t), dimension(:), allocatable :: entry
+ type(alt_entry_t), dimension(:,:), allocatable :: alt_entry
+ contains
+ procedure :: init => simulation_init
+ end type simulation_t
+
+
+contains
+
+ subroutine alt_entry_init (entry, local)
+ class(alt_entry_t), intent(inout), target :: entry
+ type(rt_data_t), intent(inout), target :: local
+ integer :: i
+ end subroutine alt_entry_init
+
+ subroutine simulation_init (simulation, &
+ integrate, generate, local, global, alt_env)
+ class(simulation_t), intent(out), target :: simulation
+ logical, intent(in) :: integrate, generate
+ type(rt_data_t), intent(inout), target :: local
+ type(rt_data_t), intent(inout), optional, target :: global
+ type(rt_data_t), dimension(:), intent(inout), optional, target :: alt_env
+ simulation%local => local
+ allocate (simulation%entry (1))
+ if (present (alt_env)) then
+ simulation%n_alt = size (alt_env)
+ end if
+ end subroutine simulation_init
+
+end module simulations
+
+
+program main_ut
+ use iso_varying_string, string_t => varying_string
+ use parser, only: parse_tree_t
+ use rt_data
+ use simulations
+ implicit none
+ call simulations_10 (6)
+
+contains
+
+ subroutine simulations_10 (u)
+ integer, intent(in) :: u
+ type(rt_data_t), target :: global
+ type(rt_data_t), dimension(1), target :: alt_env
+ type(parse_tree_t) :: pt_weight
+ type(simulation_t), target :: simulation
+
+ call global%global_init ()
+ call alt_env(1)%local_init (global)
+ call alt_env(1)%activate ()
+
+ !!!! This causes the pointer hiccup
+ alt_env(1)%pn%weight_expr => pt_weight%get_root_ptr ()
+ call simulation%init (.true., .true., global, alt_env=alt_env)
+
+ end subroutine simulations_10
+
+end program main_ut
Index: Fortran/gfortran/regression/c-interop/allocatable-dummy-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/allocatable-dummy-c.c
@@ -0,0 +1,54 @@
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+struct t {
+ float xyz[3];
+ int id;
+};
+
+extern void testit_f_bind_c (CFI_cdesc_t *a, float x, float y, float z);
+extern void testit_c (CFI_cdesc_t *a, float x, float y, float z);
+
+void testit_c (CFI_cdesc_t *a, float x, float y, float z)
+{
+ struct t *tp;
+
+ /* Check that the allocatable dummy is unallocated on entry and do
+ some other sanity checks. */
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (a->rank)
+ abort ();
+ if (a->base_addr)
+ abort ();
+
+ /* Allocate and initialize the output argument. */
+ CFI_allocate (a, NULL, NULL, 0);
+ if (!a->base_addr)
+ abort ();
+ tp = (struct t *) CFI_address (a, NULL);
+ tp->id = 42;
+ tp->xyz[0] = 0.0;
+ tp->xyz[1] = 0.0;
+ tp->xyz[2] = 0.0;
+
+ /* Now call the Fortran function, which is supposed to automatically
+ deallocate the object we just created above and point the descriptor
+ at a different object. */
+ testit_f_bind_c (a, x, y, z);
+
+ /* Make sure we've got an allocated object, initialized as we
+ expect. */
+ if (!a->base_addr)
+ abort ();
+ tp = (struct t *) CFI_address (a, NULL);
+ if (tp->id != -1)
+ abort ();
+ if (tp->xyz[0] != x || tp->xyz[1] != y || tp->xyz[2] != z)
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/allocatable-dummy.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/allocatable-dummy.f90
@@ -0,0 +1,98 @@
+! PR 101308
+! PR 92621(?)
+! { dg-do run }
+! { dg-additional-sources "allocatable-dummy-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! TS 29113
+! 6.3 Argument association
+!
+! When a Fortran procedure that has an INTENT(OUT) allocatable dummy
+! argument is invoked by a C function, and the actual argument in the C
+! function is the address of a C descriptor that describes an allocated
+! allocatable variable, the variable is deallocated on entry to the
+! Fortran procedure.
+
+! When a C function is invoked from a Fortran procedure via an interface
+! with an INTENT(OUT) allocatable dummy argument, and the actual
+! argument in the reference to the C function is an allocated
+! allocatable variable, the variable is deallocated on invocation
+! (before execution of the C function begins).
+
+module m
+ use iso_c_binding
+
+ type, bind (c) :: t
+ real(C_FLOAT) :: xyz(3)
+ integer(C_INT) :: id
+ end type
+
+ interface
+ subroutine testit_c (a, x, y, z) bind (c)
+ use iso_c_binding
+ import :: t
+ type (t), allocatable, intent(out) :: a
+ real(C_FLOAT), value, intent(in) :: x, y, z
+ end subroutine
+ end interface
+
+ contains
+
+ subroutine testit_f (a, x, y, z)
+ type (t), allocatable, intent(out) :: a
+ real(C_FLOAT), value, intent(in) :: x, y, z
+ if (allocated (a)) stop 201
+ allocate (a)
+ a%id = 69
+ a%xyz(1) = x
+ a%xyz(2) = y
+ a%xyz(3) = z
+ end subroutine
+
+ subroutine testit_f_bind_c (a, x, y, z) bind (c)
+ type (t), allocatable, intent(out) :: a
+ real(C_FLOAT), value, intent(in) :: x, y, z
+ if (allocated (a)) stop 301
+ allocate (a)
+ a%id = -1
+ a%xyz(1) = x
+ a%xyz(2) = y
+ a%xyz(3) = z
+ end subroutine
+
+end module
+
+program test
+ use iso_c_binding
+ use m
+
+ type (t), allocatable :: b
+
+ if (allocated (b)) stop 401
+
+ ! Try the regular Fortran test routine.
+ allocate (b)
+ call testit_f (b, 1.0, 2.0, 3.0)
+ if (.not. allocated (b)) stop 402
+ deallocate (b)
+ if (allocated (b)) stop 403
+
+ ! Try the test routine written in Fortran with C binding.
+ allocate (b)
+ call testit_f_bind_c (b, 1.0, 2.0, 3.0)
+ if (.not. allocated (b)) stop 404
+ deallocate (b)
+ if (allocated (b)) stop 405
+
+ ! Try the test routine written in C. This calls testit_f_bind_c
+ ! before returning, so make sure that's what we've got when returning.
+ allocate (b)
+ call testit_c (b, -1.0, -2.0, -3.0)
+ if (.not. allocated (b)) stop 406
+ if (b%id .ne. -1) stop 407
+ if (b%xyz(1) .ne. -1.0) stop 408
+ if (b%xyz(2) .ne. -2.0) stop 408
+ if (b%xyz(3) .ne. -3.0) stop 408
+ deallocate (b)
+
+end program
Index: Fortran/gfortran/regression/c-interop/allocatable-optional-pointer.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/allocatable-optional-pointer.f90
@@ -0,0 +1,23 @@
+! { dg-do compile}
+!
+! TS 29113
+! 5.3 ALLOCATABLE, OPTIONAL, and POINTER attributes
+! The ALLOCATABLE, OPTIONAL, and POINTER attributes may be specified
+! for a dummy argument in a procedure interface that has the BIND
+! attribute.
+
+subroutine test (a, b, c)
+ integer, allocatable :: a
+ integer, optional :: b
+ integer, pointer :: c
+
+ interface
+ subroutine ctest (aa, bb, cc) bind (c)
+ integer, allocatable :: aa
+ integer, optional :: bb
+ integer, pointer :: cc
+ end subroutine
+ end interface
+
+ call ctest (a, b, c)
+end subroutine
Index: Fortran/gfortran/regression/c-interop/allocate-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/allocate-c.c
@@ -0,0 +1,168 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+struct s {
+ int i;
+ double d;
+};
+
+/* External entry point. */
+extern void ctest (void);
+
+void
+ctest (void)
+{
+ CFI_CDESC_T(3) desc;
+ CFI_cdesc_t *dv = (CFI_cdesc_t *) &desc;
+ CFI_index_t ex[3], lb[3], ub[3];
+ CFI_index_t sm;
+ int i;
+
+ /* Allocate and deallocate a scalar. */
+ sm = sizeof (struct s);
+ check_CFI_status ("CFI_establish",
+ CFI_establish (dv, NULL, CFI_attribute_allocatable,
+ CFI_type_struct, sm,
+ 0, NULL));
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (dv, NULL, NULL, 69));
+ dump_CFI_cdesc_t (dv);
+ if (dv->base_addr == NULL)
+ abort ();
+ /* The elem_len argument only overrides the initial value in the
+ descriptor for character types. */
+ if (dv->elem_len != sm)
+ abort ();
+ check_CFI_status ("CFI_deallocate",
+ CFI_deallocate (dv));
+ /* The base_addr member of the C descriptor becomes a null pointer. */
+ if (dv->base_addr != NULL)
+ abort ();
+
+ /* Try an array. We are going to test the requirement that:
+ The supplied lower and upper bounds override any current
+ dimension information in the C descriptor.
+ so we'll stuff different values in the descriptor to start with. */
+ ex[0] = 3;
+ ex[1] = 4;
+ ex[2] = 5;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (dv, NULL, CFI_attribute_pointer,
+ CFI_type_double, 0, 3, ex));
+ lb[0] = 1;
+ lb[1] = 2;
+ lb[2] = 3;
+ ub[0] = 10;
+ ub[1] = 5;
+ ub[2] = 10;
+ sm = sizeof (double);
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (dv, lb, ub, 20));
+ dump_CFI_cdesc_t (dv);
+ if (dv->base_addr == NULL)
+ abort ();
+ /* The element sizes passed to both CFI_establish and CFI_allocate should
+ have been ignored in favor of using the constant size of the type. */
+ if (dv->elem_len != sm)
+ abort ();
+
+ /* Check extents and strides; we expect the allocated array to
+ be contiguous so the stride computation should be straightforward
+ no matter what the lower bound is. */
+ for (i = 0; i < 3; i++)
+ {
+ CFI_index_t extent = ub[i] - lb[i] + 1;
+ if (dv->dim[i].lower_bound != lb[i])
+ abort ();
+ if (dv->dim[i].extent != extent)
+ abort ();
+ /* pr93524 */
+ if (dv->dim[i].sm != sm)
+ abort ();
+ sm *= extent;
+ }
+ check_CFI_status ("CFI_deallocate",
+ CFI_deallocate (dv));
+ if (dv->base_addr != NULL)
+ abort ();
+
+ /* Similarly for a character array, except that we expect the
+ elem_len provided to CFI_allocate to prevail. We set the elem_len
+ to the same size as the array element in the previous example, so
+ the bounds and strides should all be the same. */
+ ex[0] = 3;
+ ex[1] = 4;
+ ex[2] = 5;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (dv, NULL, CFI_attribute_allocatable,
+ CFI_type_char, 4, 3, ex));
+ lb[0] = 1;
+ lb[1] = 2;
+ lb[2] = 3;
+ ub[0] = 10;
+ ub[1] = 5;
+ ub[2] = 10;
+ sm = sizeof (double);
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (dv, lb, ub, sm));
+ dump_CFI_cdesc_t (dv);
+ if (dv->base_addr == NULL)
+ abort ();
+ if (dv->elem_len != sm)
+ abort ();
+
+ /* Check extents and strides; we expect the allocated array to
+ be contiguous so the stride computation should be straightforward
+ no matter what the lower bound is. */
+ for (i = 0; i < 3; i++)
+ {
+ CFI_index_t extent = ub[i] - lb[i] + 1;
+ if (dv->dim[i].lower_bound != lb[i])
+ abort ();
+ if (dv->dim[i].extent != extent)
+ abort ();
+ /* pr93524 */
+ if (dv->dim[i].sm != sm)
+ abort ();
+ sm *= extent;
+ }
+ check_CFI_status ("CFI_deallocate",
+ CFI_deallocate (dv));
+ if (dv->base_addr != NULL)
+ abort ();
+
+ /* Signed char is not a Fortran character type. Here we expect it to
+ ignore the elem_len argument and use the size of the type. */
+ ex[0] = 3;
+ ex[1] = 4;
+ ex[2] = 5;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (dv, NULL, CFI_attribute_allocatable,
+ CFI_type_signed_char, 4, 3, ex));
+ lb[0] = 1;
+ lb[1] = 2;
+ lb[2] = 3;
+ ub[0] = 10;
+ ub[1] = 5;
+ ub[2] = 10;
+ sm = sizeof (double);
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (dv, lb, ub, sm));
+ dump_CFI_cdesc_t (dv);
+ if (dv->base_addr == NULL)
+ abort ();
+ if (dv->elem_len != sizeof (signed char))
+ abort ();
+
+ check_CFI_status ("CFI_deallocate",
+ CFI_deallocate (dv));
+ if (dv->base_addr != NULL)
+ abort ();
+
+}
+
Index: Fortran/gfortran/regression/c-interop/allocate-errors-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/allocate-errors-c.c
@@ -0,0 +1,109 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+struct s {
+ int i;
+ double d;
+};
+
+static long buf[5][4][3];
+
+/* External entry point. */
+extern void ctest (void);
+
+void
+ctest (void)
+{
+ int bad = 0;
+ int status;
+ CFI_CDESC_T(3) desc;
+ CFI_cdesc_t *dv = (CFI_cdesc_t *) &desc;
+ CFI_index_t ex[3], lb[3], ub[3];
+ CFI_index_t sm;
+
+ /* On entry, the base_addr member of the C descriptor shall be a null
+ pointer. */
+ sm = sizeof (struct s);
+ check_CFI_status ("CFI_establish",
+ CFI_establish (dv, NULL, CFI_attribute_allocatable,
+ CFI_type_struct, sm,
+ 0, NULL));
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (dv, NULL, NULL, 69));
+ status = CFI_allocate (dv, NULL, NULL, 42);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for CFI_allocate of already-allocated object\n");
+ bad ++;
+ }
+ check_CFI_status ("CFI_deallocate",
+ CFI_deallocate (dv));
+
+ /* The attribute member of the C descriptor shall have a value of
+ CFI_attribute_allocatable or CFI_attribute_pointer. */
+ ex[0] = 3;
+ ex[1] = 4;
+ ex[2] = 5;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (dv, NULL, CFI_attribute_other,
+ CFI_type_long, 0, 3, ex));
+ lb[0] = 1;
+ lb[1] = 2;
+ lb[2] = 3;
+ ub[0] = 10;
+ ub[1] = 5;
+ ub[2] = 10;
+ sm = sizeof (long);
+ status = CFI_allocate (dv, lb, ub, 20);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for CFI_allocate of CFI_attribute_other object\n");
+ bad ++;
+ }
+
+ /* dv shall be the address of a C descriptor describing the object.
+ It shall have been allocated using the same mechanism as the
+ Fortran ALLOCATE statement. */
+ ex[0] = 3;
+ ex[1] = 4;
+ ex[2] = 5;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (dv, NULL, CFI_attribute_pointer,
+ CFI_type_long, 0, 3, ex));
+ status = CFI_deallocate (dv);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for CFI_deallocate with null pointer\n");
+ bad ++;
+ }
+
+ /* This variant is disabled. In theory it should be possible for
+ the memory allocator to easily check for pointers outside the
+ heap region, but libfortran just calls free() which has no provision
+ for returning an error, and there is no other standard C interface
+ to check the validity of a pointer in the C heap either. */
+#if 0
+ check_CFI_status ("CFI_establish",
+ CFI_establish (dv, buf, CFI_attribute_pointer,
+ CFI_type_long, 0, 3, ex));
+ status = CFI_deallocate (dv);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for CFI_deallocate with non-allocated pointer\n");
+ bad ++;
+ }
+#endif
+
+ if (bad)
+ abort ();
+}
+
Index: Fortran/gfortran/regression/c-interop/allocate-errors.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/allocate-errors.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+! { dg-additional-sources "allocate-errors-c.c dump-descriptors.c" }
+! { dg-additional-options "-Wno-error -fcheck=all" }
+! { dg-warning "command-line option '-fcheck=all' is valid for Fortran but not for C" "" { target *-*-* } 0 }
+!
+! This program tests that the CFI_allocate and CFI_deallocate functions
+! properly detect invalid arguments. All the interesting things happen
+! in the corresponding C code.
+!
+! The situation here seems to be that while TS29113 defines error codes for
+! these functions, it doesn't actually require the implementation to detect
+! those errors by saying the arguments "shall be" such-and-such, e.g. it is
+! undefined behavior if they are not. In gfortran you can enable some
+! run-time checking by building with -fcheck=all.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest () bind (c)
+ end subroutine
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/allocate.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/allocate.f90
@@ -0,0 +1,19 @@
+! { dg-do run }
+! { dg-additional-sources "allocate-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests the CFI_allocate and CFI_deallocate functions.
+! All the interesting things happen in the corresponding C code.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest () bind (c)
+ end subroutine
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-1.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.3 Argument association
+! An assumed-rank dummy argument may correspond to an actual argument of
+! any rank. If the actual argument has rank zero, the dummy argument has
+! rank zero; the shape is a zero-sized array and the LBOUND and UBOUND
+! intrinsic functions, with no DIM argument, return zero-sized
+! arrays. [...]
+
+program test
+
+ call testit (42)
+
+contains
+
+ subroutine testit (x0)
+ integer :: x0(..)
+
+ ! expect to have rank 0
+ if (rank (x0) .ne. 0) stop 101
+
+ ! expect shape to be a zero-sized array
+ if (size (shape (x0)) .ne. 0) stop 102
+
+ ! expect lbound and ubound functions to return zero-sized arrays
+ if (size (lbound (x0)) .ne. 0) stop 103
+ if (size (ubound (x0)) .ne. 0) stop 104
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-2.f90
@@ -0,0 +1,48 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.3 Argument association
+! An assumed-rank dummy argument may correspond to an actual argument of
+! any rank. [...] If the actual argument has rank greater than zero, the
+! rank and extents of the dummy argument are assumed from the actual
+! argument, including the lack of a final extent in the case of an
+! assumed-size array. If the actual argument is an array and the dummy
+! argument is allocatable or a pointer, the bounds of the dummy argument
+! are assumed from the actual argument.
+
+program test
+
+ integer :: a(3, 4, 5)
+ integer :: b(-3:3, 0:4, 2:5, 10:20)
+
+ call testit (a, rank(a), shape(a), lbound(a), ubound(a))
+ call testit (b, rank(b), shape(b), lbound(b), ubound(b))
+
+contains
+
+ subroutine testit (x, r, s, l, u)
+ integer :: x(..)
+ integer :: r
+ integer :: s(r)
+ integer :: l(r)
+ integer :: u(r)
+
+ ! expect rank to match
+ if (rank (x) .ne. r) stop 101
+
+ ! expect shape to match
+ if (size (shape (x)) .ne. r) stop 102
+ if (any (shape (x) .ne. s)) stop 103
+
+ ! expect lbound and ubound functions to return rank-sized arrays.
+ ! for non-pointer/non-allocatable arrays, bounds are normalized
+ ! to be 1-based.
+ if (size (lbound (x)) .ne. r) stop 104
+ if (any (lbound (x) .ne. 1)) stop 105
+
+ if (size (ubound (x)) .ne. r) stop 106
+ if (any (ubound (x) .ne. u - l + 1)) stop 107
+ if (any (ubound (x) .ne. s)) stop 108
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-3.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.3 Argument association
+! An assumed-rank dummy argument may correspond to an actual argument of
+! any rank. [...] If the actual argument has rank greater than zero, the
+! rank and extents of the dummy argument are assumed from the actual
+! argument, including the lack of a final extent in the case of an
+! assumed-size array. If the actual argument is an array and the dummy
+! argument is allocatable or a pointer, the bounds of the dummy argument
+! are assumed from the actual argument.
+
+program test
+
+ integer, target :: a(3, 4, 5)
+ integer, target :: b(-3:3, 0:4, 2:5, 10:20)
+ integer, pointer :: aa(:,:,:)
+ integer, pointer :: bb(:,:,:,:)
+ aa => a
+ bb => b
+
+ call testit (aa, rank(a), shape(a), lbound(a), ubound(a))
+ call testit (bb, rank(b), shape(b), lbound(b), ubound(b))
+
+contains
+
+ subroutine testit (x, r, s, l, u)
+ integer, pointer :: x(..)
+ integer :: r
+ integer :: s(r)
+ integer :: l(r)
+ integer :: u(r)
+
+ ! expect rank to match
+ if (rank (x) .ne. r) stop 101
+
+ ! expect shape to match
+ if (size (shape (x)) .ne. r) stop 102
+ if (any (shape (x) .ne. s)) stop 103
+
+ ! expect lbound and ubound functions to return rank-sized arrays.
+ ! for non-pointer/non-allocatable arrays, bounds are normalized
+ ! to be 1-based.
+ if (size (lbound (x)) .ne. r) stop 104
+ if (any (lbound (x) .ne. l)) stop 105
+
+ if (size (ubound (x)) .ne. r) stop 106
+ if (any (ubound (x) .ne. u)) stop 107
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-4.f90
@@ -0,0 +1,50 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.3 Argument association
+! An assumed-rank dummy argument may correspond to an actual argument of
+! any rank. [...] If the actual argument has rank greater than zero, the
+! rank and extents of the dummy argument are assumed from the actual
+! argument, including the lack of a final extent in the case of an
+! assumed-size array. If the actual argument is an array and the dummy
+! argument is allocatable or a pointer, the bounds of the dummy argument
+! are assumed from the actual argument.
+
+program test
+
+ integer, allocatable :: a(:,:,:)
+ integer, allocatable :: b(:,:,:,:)
+
+ allocate (a(3, 4, 5))
+ allocate (b(-3:3, 0:4, 2:5, 10:20))
+
+ call testit (a, rank(a), shape(a), lbound(a), ubound(a))
+ call testit (b, rank(b), shape(b), lbound(b), ubound(b))
+
+contains
+
+ subroutine testit (x, r, s, l, u)
+ integer, allocatable :: x(..)
+ integer :: r
+ integer :: s(r)
+ integer :: l(r)
+ integer :: u(r)
+
+ ! expect rank to match
+ if (rank (x) .ne. r) stop 101
+
+ ! expect shape to match
+ if (size (shape (x)) .ne. r) stop 102
+ if (any (shape (x) .ne. s)) stop 103
+
+ ! expect lbound and ubound functions to return rank-sized arrays.
+ ! for non-pointer/non-allocatable arrays, bounds are normalized
+ ! to be 1-based.
+ if (size (lbound (x)) .ne. r) stop 104
+ if (any (lbound (x) .ne. l)) stop 105
+
+ if (size (ubound (x)) .ne. r) stop 106
+ if (any (ubound (x) .ne. u)) stop 107
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-5.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-5.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.3 Argument association
+! An assumed-rank dummy argument may correspond to an actual argument of
+! any rank. If the actual argument has rank zero, the dummy argument has
+! rank zero; the shape is a zero-sized array and the LBOUND and UBOUND
+! intrinsic functions, with no DIM argument, return zero-sized
+! arrays. [...]
+
+program test
+
+ call testit (42)
+
+contains
+
+ subroutine testit (x0) bind (c)
+ integer :: x0(..)
+
+ ! expect to have rank 0
+ if (rank (x0) .ne. 0) stop 101
+
+ ! expect shape to be a zero-sized array
+ if (size (shape (x0)) .ne. 0) stop 102
+
+ ! expect lbound and ubound functions to return zero-sized arrays
+ if (size (lbound (x0)) .ne. 0) stop 103
+ if (size (ubound (x0)) .ne. 0) stop 104
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-6.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-6.f90
@@ -0,0 +1,48 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.3 Argument association
+! An assumed-rank dummy argument may correspond to an actual argument of
+! any rank. [...] If the actual argument has rank greater than zero, the
+! rank and extents of the dummy argument are assumed from the actual
+! argument, including the lack of a final extent in the case of an
+! assumed-size array. If the actual argument is an array and the dummy
+! argument is allocatable or a pointer, the bounds of the dummy argument
+! are assumed from the actual argument.
+
+program test
+
+ integer :: a(3, 4, 5)
+ integer :: b(-3:3, 0:4, 2:5, 10:20)
+
+ call testit (a, rank(a), shape(a), lbound(a), ubound(a))
+ call testit (b, rank(b), shape(b), lbound(b), ubound(b))
+
+contains
+
+ subroutine testit (x, r, s, l, u) bind (c)
+ integer :: x(..)
+ integer :: r
+ integer :: s(r)
+ integer :: l(r)
+ integer :: u(r)
+
+ ! expect rank to match
+ if (rank (x) .ne. r) stop 101
+
+ ! expect shape to match
+ if (size (shape (x)) .ne. r) stop 102
+ if (any (shape (x) .ne. s)) stop 103
+
+ ! expect lbound and ubound functions to return rank-sized arrays.
+ ! for non-pointer/non-allocatable arrays, bounds are normalized
+ ! to be 1-based.
+ if (size (lbound (x)) .ne. r) stop 104
+ if (any (lbound (x) .ne. 1)) stop 105
+
+ if (size (ubound (x)) .ne. r) stop 106
+ if (any (ubound (x) .ne. u - l + 1)) stop 107
+ if (any (ubound (x) .ne. s)) stop 108
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-7.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-7.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.3 Argument association
+! An assumed-rank dummy argument may correspond to an actual argument of
+! any rank. [...] If the actual argument has rank greater than zero, the
+! rank and extents of the dummy argument are assumed from the actual
+! argument, including the lack of a final extent in the case of an
+! assumed-size array. If the actual argument is an array and the dummy
+! argument is allocatable or a pointer, the bounds of the dummy argument
+! are assumed from the actual argument.
+
+program test
+
+ integer, target :: a(3, 4, 5)
+ integer, target :: b(-3:3, 0:4, 2:5, 10:20)
+ integer, pointer :: aa(:,:,:)
+ integer, pointer :: bb(:,:,:,:)
+ aa => a
+ bb => b
+
+ call testit (aa, rank(a), shape(a), lbound(a), ubound(a))
+ call testit (bb, rank(b), shape(b), lbound(b), ubound(b))
+
+contains
+
+ subroutine testit (x, r, s, l, u) bind (c)
+ integer, pointer :: x(..)
+ integer :: r
+ integer :: s(r)
+ integer :: l(r)
+ integer :: u(r)
+
+ ! expect rank to match
+ if (rank (x) .ne. r) stop 101
+
+ ! expect shape to match
+ if (size (shape (x)) .ne. r) stop 102
+ if (any (shape (x) .ne. s)) stop 103
+
+ ! expect lbound and ubound functions to return rank-sized arrays.
+ ! for non-pointer/non-allocatable arrays, bounds are normalized
+ ! to be 1-based.
+ if (size (lbound (x)) .ne. r) stop 104
+ if (any (lbound (x) .ne. l)) stop 105
+
+ if (size (ubound (x)) .ne. r) stop 106
+ if (any (ubound (x) .ne. u)) stop 107
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-8.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/argument-association-assumed-rank-8.f90
@@ -0,0 +1,50 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.3 Argument association
+! An assumed-rank dummy argument may correspond to an actual argument of
+! any rank. [...] If the actual argument has rank greater than zero, the
+! rank and extents of the dummy argument are assumed from the actual
+! argument, including the lack of a final extent in the case of an
+! assumed-size array. If the actual argument is an array and the dummy
+! argument is allocatable or a pointer, the bounds of the dummy argument
+! are assumed from the actual argument.
+
+program test
+
+ integer, allocatable :: a(:,:,:)
+ integer, allocatable :: b(:,:,:,:)
+
+ allocate (a(3, 4, 5))
+ allocate (b(-3:3, 0:4, 2:5, 10:20))
+
+ call testit (a, rank(a), shape(a), lbound(a), ubound(a))
+ call testit (b, rank(b), shape(b), lbound(b), ubound(b))
+
+contains
+
+ subroutine testit (x, r, s, l, u) bind (c)
+ integer, allocatable :: x(..)
+ integer :: r
+ integer :: s(r)
+ integer :: l(r)
+ integer :: u(r)
+
+ ! expect rank to match
+ if (rank (x) .ne. r) stop 101
+
+ ! expect shape to match
+ if (size (shape (x)) .ne. r) stop 102
+ if (any (shape (x) .ne. s)) stop 103
+
+ ! expect lbound and ubound functions to return rank-sized arrays.
+ ! for non-pointer/non-allocatable arrays, bounds are normalized
+ ! to be 1-based.
+ if (size (lbound (x)) .ne. r) stop 104
+ if (any (lbound (x) .ne. l)) stop 105
+
+ if (size (ubound (x)) .ne. r) stop 106
+ if (any (ubound (x) .ne. u)) stop 107
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/assumed-type-dummy.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/assumed-type-dummy.f90
@@ -0,0 +1,84 @@
+! PR 101319
+! { dg-do compile }
+!
+! TS 29113
+! 6.3 Argument association
+!
+! An assumed-type dummy argument shall not correspond to an actual argument
+! that is of a derived type that has type parameters, type-bound procedures,
+! or final subroutines.
+!
+! In the 2018 Fortran standard, this requirement appears as:
+!
+! 15.5.2.4 Ordinary dummy variables
+!
+! If the actual argument is of a derived type that has type parameters,
+! type-bound procedures, or final subroutines, the dummy argument shall
+! not be assumed-type.
+!
+! This file contains code that is expected to produce errors.
+
+module m
+
+ ! basic derived type
+ type :: t1
+ real*8 :: xyz (3)
+ end type
+
+ ! derived type with type parameters
+ type t2 (k, l)
+ integer, kind :: k
+ integer, len :: l
+ real(k) :: a(l)
+ end type
+
+ ! derived type with a type-bound procedure
+ type :: t3
+ integer :: xyz(3)
+ contains
+ procedure, pass :: frob => frob_t3
+ end type
+
+ ! derived type with a final subroutine
+ type :: t4
+ integer :: xyz(3)
+ contains
+ final :: final_t4
+ end type
+
+contains
+
+ ! implementation of the type-bound procedure for t3 above
+ subroutine frob_t3 (a)
+ class (t3) :: a
+ a%xyz = 0
+ end subroutine
+
+ ! implementation of the final subroutine for t4 above
+ subroutine final_t4 (a)
+ type (t4) :: a
+ a%xyz = 0
+ end subroutine
+
+ ! useless subroutine with an assumed-type dummy.
+ subroutine s1 (a)
+ type(*) :: a
+ end subroutine
+
+ ! test procedure
+ subroutine testit
+ type(t1) :: a1
+ type(t2(8,20)) :: a2
+ type(t3) :: a3
+ type(t4) :: a4
+
+ call s1 (a1) ! OK
+ call s1 (a2) ! { dg-error "assumed-type dummy" }
+ call s1 (a3) ! { dg-error "assumed-type dummy" }
+ call s1 (a4) ! { dg-error "assumed-type dummy" }
+ end subroutine
+
+end module
+
+
+
Index: Fortran/gfortran/regression/c-interop/c-interop.exp
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c-interop.exp
@@ -0,0 +1,57 @@
+# Copyright (C) 2005-2023 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# .
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gfortran-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+global gfortran_test_path
+global gfortran_aux_module_flags
+set gfortran_test_path $srcdir/$subdir
+set gfortran_aux_module_flags "-Werror -std=f2018"
+proc dg-compile-aux-modules { args } {
+ global gfortran_test_path
+ global gfortran_aux_module_flags
+ if { [llength $args] != 2 } {
+ error "dg-compile-aux-modules: needs one argument"
+ return
+ }
+
+ set level [info level]
+ if { [info procs dg-save-unknown] != [list] } {
+ rename dg-save-unknown dg-save-unknown-level-$level
+ }
+
+ dg-test $gfortran_test_path/[lindex $args 1] "" $gfortran_aux_module_flags
+ # cleanup-modules is intentionally not invoked here.
+
+ if { [info procs dg-save-unknown-level-$level] != [list] } {
+ rename dg-save-unknown-level-$level dg-save-unknown
+ }
+}
+
+# Main loop.
+gfortran-dg-runtest [lsort \
+ [find $srcdir/$subdir *.\[fF\]{,90,95,03,08} ] ] "" "-Werror"
+
+# All done.
+dg-finish
Index: Fortran/gfortran/regression/c-interop/c1255-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c1255-1.f90
@@ -0,0 +1,83 @@
+! PR92482
+! { dg-do compile }
+!
+! TS 29113
+! C1255 (R1230) If proc-language-binding-spec is specified for a procedure,
+! each dummy argument shall be an interoperable procedure (15.3.7)
+! or a variable that is interoperable (15.3.5, 15.3.6), assumed shape,
+! assumed rank, assumed type, of assumed character length, or has the
+! ALLOCATABLE or POINTER attribute. If proc-language-binding-spec is
+! specified for a function, the function result shall be an interoperable
+! scalar variable.
+
+module m
+
+ interface
+
+ ! dummy is interoperable procedure
+ subroutine s1 (x) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ interface
+ function x (a, b) bind (c)
+ use ISO_C_BINDING
+ integer(C_INT) :: a, b
+ integer(C_INT) :: x
+ end function
+ end interface
+ end subroutine
+
+ ! dummy is interoperable variable
+ subroutine s2 (x) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT) :: x
+ end subroutine
+
+ ! dummy is assumed-shape array variable
+ subroutine s3 (x) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT) :: x(:)
+ end subroutine
+
+ ! dummy is an assumed-rank array variable
+ subroutine s4 (x) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT) :: x(..)
+ end subroutine
+
+ ! dummy is assumed-type variable
+ subroutine s5 (x) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ type(*) :: x
+ end subroutine
+
+ ! dummy is assumed length character variable
+ subroutine s6 (x) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ character(len=*) :: x
+ end subroutine
+
+ ! dummy has allocatable or pointer attribute
+ subroutine s7 (x, y) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT), allocatable :: x
+ integer(C_INT), pointer :: y
+ end subroutine
+
+ ! function result shall be an interoperable scalar variable
+ function f (x) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT) :: x
+ integer(C_INT) :: f
+ end function
+
+ end interface
+end module
+
Index: Fortran/gfortran/regression/c-interop/c1255-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c1255-2.f90
@@ -0,0 +1,106 @@
+! { dg-do compile }
+!
+! TS 29113
+! C1255 (R1230) If proc-language-binding-spec is specified for a procedure,
+! each dummy argument shall be an interoperable procedure (15.3.7)
+! or a variable that is interoperable (15.3.5, 15.3.6), assumed shape,
+! assumed rank, assumed type, of assumed character length, or has the
+! ALLOCATABLE or POINTER attribute. If proc-language-binding-spec is
+! specified for a function, the function result shall be an interoperable
+! scalar variable.
+!
+! This file contains code that is expected to produce errors.
+
+
+module m1
+ ! type to use for examples below
+ type t
+ integer :: foo
+ real :: bar
+ end type
+end module
+
+module m2
+
+ interface
+
+ ! dummy is a procedure that is not interoperable
+ subroutine s1 (x) bind (c)
+ use ISO_C_BINDING
+ use m1
+ implicit none
+ interface
+ function x (a, b) bind (c) ! { dg-error "not C interoperable" }
+ use ISO_C_BINDING
+ use m1
+ integer(C_INT) :: a
+ class(t) :: b !
+ integer(C_INT) :: x
+ end function
+ end interface
+ end subroutine
+
+ ! dummy is of a type that is not interoperable
+ subroutine s2 (x) bind (c) ! { dg-error "not C interoperable" }
+ use ISO_C_BINDING
+ use m1
+ implicit none
+ class(t) :: x
+ end subroutine
+
+ ! dummy is an array that is not of interoperable type and not
+ ! assumed-shape or assumed-rank
+ subroutine s3 (x) bind (c) ! { dg-error "not C interoperable" }
+ use ISO_C_BINDING
+ use m1
+ implicit none
+ class(t) :: x(3, 3)
+ end subroutine
+
+ subroutine s4 (n, x) bind (c) ! { dg-error "not C interoperable" }
+ use ISO_C_BINDING
+ use m1
+ implicit none
+ integer(C_INT) :: n
+ class(t) :: x(n)
+ end subroutine
+
+ ! This fails with a bogus error even without C binding.
+ subroutine s5 (x) bind (c) ! { dg-error "not C interoperable" }
+ use ISO_C_BINDING
+ use m1
+ implicit none
+ class(t) :: x(*) ! { dg-bogus "not yet been implemented" "pr46991" }
+ ! { dg-bogus "has no IMPLICIT type" "pr46991" { target "*-*-*" } 68 }
+ end subroutine
+
+ subroutine s5a (x)
+ use ISO_C_BINDING
+ use m1
+ implicit none
+ class(t) :: x(*) ! { dg-bogus "not yet been implemented" "pr46991" }
+ ! { dg-bogus "has no IMPLICIT type" "pr46991" { target "*-*-*" } 76 }
+ end subroutine
+
+ ! function result is not a scalar
+ function f (x) bind (c) ! { dg-error "not C interoperable" }
+ use ISO_C_BINDING
+ use m1
+ implicit none
+ integer(C_INT) :: x
+ type(t) :: f
+ end function
+
+ ! function result is a type that is not interoperable
+ function g (x) bind (c) ! { dg-error "BIND\\(C\\)" }
+ use ISO_C_BINDING
+ use m1
+ implicit none
+ integer(C_INT) :: x
+ integer(C_INT), allocatable :: g
+ end function
+
+ end interface
+
+end module
+
Index: Fortran/gfortran/regression/c-interop/c1255a.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c1255a.f90
@@ -0,0 +1,40 @@
+! { dg-do compile }
+!
+! TS 29113
+! C1255a (R1230) A dummy argument of a procedure that has a
+! proc-language-binding-spec shall not have both the OPTIONAL and
+! VALUE attributes.
+!
+! This file contains code that is expected to produce errors.
+
+module m
+
+ interface
+
+ ! This one is OK.
+ subroutine s1 (x, y) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT) :: x
+ integer(C_INT), optional :: y
+ end subroutine
+
+ ! This one is OK too.
+ subroutine s2 (x, y) bind (c)
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT) :: x
+ integer(C_INT), value :: y
+ end subroutine
+
+ ! This one is bad.
+ subroutine s3 (x, y) bind (c) ! { dg-error "BIND\\(C\\)" }
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT) :: x
+ integer(C_INT), optional, value :: y
+ end subroutine
+
+ end interface
+
+end module
Index: Fortran/gfortran/regression/c-interop/c407a-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c407a-1.f90
@@ -0,0 +1,55 @@
+! { dg-do compile}
+!
+! TS 29113
+! C407a An assumed-type entity shall be a dummy variable that does not
+! have the ALLOCATABLE, CODIMENSION, INTENT(OUT), POINTER, or VALUE
+! attribute and is not an explicit-shape array.
+!
+! This test file contains tests that are expected to all pass.
+
+! Check basic usage with no attributes.
+
+module m
+ interface
+ subroutine g (a, b)
+ implicit none
+ type(*) :: a
+ integer :: b
+ end subroutine
+ end interface
+end module
+
+subroutine s0 (x)
+ use m
+ implicit none
+ type(*) :: x
+
+ call g (x, 1)
+end subroutine
+
+! Check that other attributes that can normally apply to dummy variables
+! are allowed.
+
+subroutine s1 (a, b, c, d, e, f, g, h)
+ implicit none
+ type(*), asynchronous :: a
+ type(*), contiguous :: b(:,:)
+ type(*), dimension (:) :: c
+ type(*), intent(in) :: d
+ type(*), intent(inout) :: e
+ type(*), optional :: f
+ type(*), target :: g
+ type(*), volatile :: h
+
+end subroutine
+
+! Check that non-explicit-shape arrays are allowed.
+
+subroutine s2 (a, b, c)
+ implicit none
+ type(*) :: a(:) ! assumed-shape
+ type(*) :: b(*) ! assumed-size
+ type(*) :: c(..) ! assumed-rank
+
+end subroutine
+
Index: Fortran/gfortran/regression/c-interop/c407a-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c407a-2.f90
@@ -0,0 +1,88 @@
+! { dg-do compile }
+! { dg-additional-options "-fcoarray=single" }
+!
+! TS 29113
+! C407a An assumed-type entity shall be a dummy variable that does not
+! have the ALLOCATABLE, CODIMENSION, INTENT(OUT), POINTER, or VALUE
+! attribute and is not an explicit-shape array.
+!
+! This test file contains tests that are expected to issue diagnostics
+! for invalid code.
+
+! Check that diagnostics are issued when type(*) is used to declare things
+! that are not dummy variables.
+
+subroutine s0 (a)
+ implicit none
+ integer :: a
+
+ integer :: goodlocal
+ type(*) :: badlocal ! { dg-error "Assumed.type" }
+
+ integer :: goodcommon
+ type(*) :: badcommon ! { dg-error "Assumed.type" }
+ common /frob/ goodcommon, badcommon
+
+ integer :: goodstatic
+ type(*) :: badstatic ! { dg-error "Assumed.type" }
+ save goodstatic, badstatic
+
+ block
+ integer :: goodlocal2
+ type(*) :: badlocal2 ! { dg-error "Assumed.type" }
+ end block
+
+end subroutine
+
+module m
+ integer :: goodmodvar
+ type(*) :: badmodvar ! { dg-error "Assumed.type" }
+ save goodmodvar, badmodvar
+
+ type :: t
+ integer :: goodcomponent
+ type(*) :: badcomponent ! { dg-error "Assumed.type" }
+ end type
+end module
+
+! Check that diagnostics are issued when type(*) is used in combination
+! with the forbidden attributes.
+
+subroutine s1 (a) ! { dg-error "Assumed.type" }
+ implicit none
+ type(*), allocatable :: a
+end subroutine
+
+subroutine s2 (b) ! { dg-error "Assumed.type" }
+ implicit none
+ type(*), codimension[*] :: b(:,:)
+end subroutine
+
+subroutine s3 (c) ! { dg-error "Assumed.type" }
+ implicit none
+ type(*), intent(out) :: c
+end subroutine
+
+subroutine s4 (d) ! { dg-error "Assumed.type" }
+ implicit none
+ type(*), pointer :: d
+end subroutine
+
+subroutine s5 (e) ! { dg-error "Assumed.type" }
+ implicit none
+ type(*), value :: e
+end subroutine
+
+! Check that diagnostics are issued when type(*) is used to declare
+! a dummy variable that is an explicit-shape array.
+
+subroutine s6 (n, f) ! { dg-error "Assumed.type" }
+ implicit none
+ integer n
+ type(*) :: f(n,n)
+end subroutine
+
+subroutine s7 (g) ! { dg-error "Assumed.type" }
+ implicit none
+ type(*) :: g(10)
+end subroutine
Index: Fortran/gfortran/regression/c-interop/c407b-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c407b-1.f90
@@ -0,0 +1,107 @@
+! { dg-do compile}
+!
+! TS 29113
+! C407b An assumed-type variable name shall not appear in a designator
+! or expression except as an actual argument corresponding to a dummy
+! argument that is assumed-type, or as the first argument to any of
+! the intrinsic and intrinsic module functions IS_CONTIGUOUS, LBOUND,
+! PRESENT, RANK, SHAPE, SIZE, UBOUND, and C_LOC.
+!
+! This test file contains tests that are expected to all pass.
+
+! Check that passing an assumed-type variable as an actual argument
+! corresponding to an assumed-type dummy works.
+
+module m
+ interface
+ subroutine g (a, b)
+ implicit none
+ type(*) :: a
+ integer :: b
+ end subroutine
+ end interface
+end module
+
+subroutine s0 (x)
+ use m
+ implicit none
+ type(*) :: x
+
+ call g (x, 1)
+end subroutine
+
+! Check that calls to the permitted intrinsic functions work.
+
+function test_is_contiguous (a)
+ implicit none
+ type(*) :: a(*)
+ logical :: test_is_contiguous
+
+ test_is_contiguous = is_contiguous (a)
+end function
+
+function test_lbound (a)
+ implicit none
+ type(*) :: a(:)
+ integer :: test_lbound
+
+ test_lbound = lbound (a, 1)
+end function
+
+function test_present (a)
+ implicit none
+ type(*), optional :: a(*)
+ logical :: test_present
+
+ test_present = present (a)
+end function
+
+function test_rank (a)
+ implicit none
+ type(*) :: a(*)
+ integer :: test_rank
+
+ test_rank = rank (a)
+end function
+
+function test_shape (a)
+ implicit none
+ type(*) :: a(:) ! assumed-shape array so shape intrinsic works
+ integer :: test_shape
+
+ integer :: temp, i
+ integer, dimension (rank (a)) :: ashape
+
+ temp = 1
+ ashape = shape (a)
+ do i = 1, rank (a)
+ temp = temp * ashape (i)
+ end do
+ test_shape = temp
+end function
+
+function test_size (a)
+ implicit none
+ type(*) :: a(:)
+ integer :: test_size
+
+ test_size = size (a)
+end function
+
+function test_ubound (a)
+ implicit none
+ type(*) :: a(:)
+ integer :: test_ubound
+
+ test_ubound = ubound (a, 1)
+end function
+
+function test_c_loc (a)
+ use iso_c_binding
+ implicit none
+ type(*), target :: a(*)
+ type(c_ptr) :: test_c_loc
+
+ test_c_loc = c_loc (a)
+end function
+
Index: Fortran/gfortran/regression/c-interop/c407b-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c407b-2.f90
@@ -0,0 +1,150 @@
+! PR 101337
+! { dg-do compile}
+!
+! TS 29113
+! C407b An assumed-type variable name shall not appear in a designator
+! or expression except as an actual argument corresponding to a dummy
+! argument that is assumed-type, or as the first argument to any of
+! the intrinsic and intrinsic module functions IS_CONTIGUOUS, LBOUND,
+! PRESENT, RANK, SHAPE, SIZE, UBOUND, and C_LOC.
+!
+! This file contains tests that are expected to give diagnostics.
+
+! Check that passing an assumed-type variable as an actual argument
+! corresponding to a non-assumed-type dummy gives a diagnostic.
+
+module m
+ interface
+ subroutine f (a, b)
+ implicit none
+ integer :: a
+ integer :: b
+ end subroutine
+ subroutine g (a, b)
+ implicit none
+ type(*) :: a
+ integer :: b
+ end subroutine
+ subroutine h (a, b)
+ implicit none
+ type(*) :: a(*)
+ integer :: b
+ end subroutine
+ end interface
+end module
+
+subroutine s0 (x)
+ use m
+ implicit none
+ type(*) :: x
+
+ call g (x, 1)
+ call f (x, 1) ! { dg-error "Type mismatch" }
+ call h (x, 1) ! Scalar to type(*),dimension(*): Invalid in TS29113 but valid since F2018
+end subroutine
+
+! Check that you can't use an assumed-type array variable in an array
+! element or section designator.
+
+subroutine s1 (x, y)
+ use m
+ implicit none
+ integer :: x(*)
+ type(*) :: y(*)
+
+ call f (x(1), 1)
+ call g (y(1), 1) ! { dg-error "Assumed.type" }
+ call h (y, 1) ! ok
+ call h (y(1:3:1), 1) ! { dg-error "Assumed.type" }
+end subroutine
+
+! Check that you can't use an assumed-type array variable in other
+! expressions. This is clearly not exhaustive since few operations
+! are even plausible from a type perspective.
+
+subroutine s2 (x, y)
+ implicit none
+ type(*) :: x, y
+ integer :: i
+
+ ! select type
+ select type (x) ! { dg-error "Assumed.type|Selector shall be polymorphic" }
+ type is (integer)
+ i = 0
+ type is (real)
+ i = 1
+ class default
+ i = -1
+ end select
+
+ ! relational operations
+ if (x & ! { dg-error "Assumed.type" "pr101337" }
+ .eq. y) then ! { dg-error "Assumed.type" }
+ return
+ end if
+ if (.not. (x & ! { dg-error "Assumed.type" "pr101337" }
+ .ne. y)) then ! { dg-error "Assumed.type" }
+ return
+ end if
+ if (.not. x) then ! { dg-error "Assumed.type" }
+ return
+ end if
+
+ ! assignment
+ x & ! { dg-error "Assumed.type" }
+ = y ! { dg-error "Assumed.type" }
+ i = x ! { dg-error "Assumed.type" }
+ y = i ! { dg-error "Assumed.type" }
+
+ ! arithmetic
+ i = x + 1 ! { dg-error "Assumed.type" }
+ i = -y ! { dg-error "Assumed.type" }
+ i = (x & ! { dg-error "Assumed.type" "pr101337" }
+ + y) ! { dg-error "Assumed.type" }
+
+ ! computed go to
+ goto (10, 20, 30), x ! { dg-error "Assumed.type|must be a scalar integer" }
+10 continue
+20 continue
+30 continue
+
+ ! do loops
+ do i = 1, x ! { dg-error "Assumed.type" }
+ continue
+ end do
+ do x = 1, i ! { dg-error "Assumed.type" }
+ continue
+ end do
+
+end subroutine
+
+! Check that calls to disallowed intrinsic functions produce a diagnostic.
+! Again, this isn't exhaustive, there are just too many intrinsics and
+! hardly any of them are plausible.
+
+subroutine s3 (x, y)
+ implicit none
+ type(*) :: x, y
+ integer :: i
+
+ i = bit_size (x) ! { dg-error "Assumed.type" }
+ i = exponent (x) ! { dg-error "Assumed.type" }
+
+ if (extends_type_of (x, & ! { dg-error "Assumed.type" }
+ y)) then ! { dg-error "Assumed.type" "pr101337" }
+ return
+ end if
+
+ if (same_type_as (x, & ! { dg-error "Assumed.type" }
+ y)) then ! { dg-error "Assumed.type" "pr101337" }
+ return
+ end if
+
+ i = storage_size (x) ! { dg-error "Assumed.type" }
+
+ i = iand (x, & ! { dg-error "Assumed.type" }
+ y) ! { dg-error "Assumed.type" "pr101337" }
+
+ i = kind (x) ! { dg-error "Assumed.type" }
+
+end subroutine
Index: Fortran/gfortran/regression/c-interop/c407c-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c407c-1.f90
@@ -0,0 +1,63 @@
+! PR101333
+! { dg-do compile}
+!
+! TS 29113
+! C407c An assumed-type actual argument that corresponds to an
+! assumed-rank dummy argument shall be assumed-shape or assumed-rank.
+!
+! This constraint is renumbered C711 in the 2018 Fortran standard.
+
+module m
+ interface
+ subroutine g (a, b)
+ implicit none
+ type(*) :: a(..)
+ integer :: b
+ end subroutine
+ end interface
+end module
+
+! Check that assumed-shape works.
+
+subroutine s0 (x)
+ use m
+ implicit none
+ type(*) :: x(:)
+
+ call g (x, 1)
+end subroutine
+
+! Check that assumed-rank works.
+
+subroutine s1 (x)
+ use m
+ implicit none
+ type(*) :: x(..)
+
+ call g (x, 1)
+end subroutine
+
+! Check that assumed-size gives an error.
+
+subroutine s2 (x)
+ use m
+ implicit none
+ type(*) :: x(*)
+
+ call g (x, 1) ! { dg-error "Assumed-type actual argument at .1. corresponding to assumed-rank dummy argument 'a' must be assumed-shape or assumed-rank" }
+end subroutine
+
+! Check that a scalar gives an error.
+subroutine s3 (x)
+ use m
+ implicit none
+ type(*) :: x
+
+ call g (x, 1) ! { dg-error "Assumed.type" }
+end subroutine
+
+! Explicit-shape assumed-type actual arguments are forbidden implicitly
+! by c407a (C709 in the 2018 standard). They're not allowed as dummy
+! arguments, and assumed-type entities can only be declared as dummy
+! arguments, so there is no other way to construct one to pass as an
+! actual argument.
Index: Fortran/gfortran/regression/c-interop/c516.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c516.f90
@@ -0,0 +1,109 @@
+! PR 101320
+! { dg-do compile }
+!
+! TS 29113
+! C516 The ALLOCATABLE or POINTER attribute shall not be specified for
+! a default-initialized dummy argument of a procedure that has a
+! proc-language-binding-spec.
+!
+! This file contains code that is expected to produce errors.
+
+module m1
+
+ type, bind(c) :: t1
+ integer :: a
+ integer :: b
+ end type
+
+
+ type, bind(c) :: t2
+ integer :: a = 0
+ integer :: b = -1
+ end type
+
+end module
+
+module m2
+
+ interface
+
+ ! First test versions with optional attributes on the argument.
+ ! TS29113 removed the constraint disallowing optional arguments
+ ! that previously used to be in C516.
+
+ ! good, no default initialization, no pointer/allocatable attribute
+ subroutine s1a (x) bind (c)
+ use m1
+ type(t1), optional :: x
+ end subroutine
+
+ ! good, no default initialization
+ subroutine s1b (x) bind (c)
+ use m1
+ type(t1), allocatable, optional :: x
+ end subroutine
+
+ ! good, no default initialization
+ subroutine s1c (x) bind (c)
+ use m1
+ type(t1), pointer, optional :: x
+ end subroutine
+
+ ! good, default initialization but no pointer/allocatable attribute
+ subroutine s2a (x) bind (c)
+ use m1
+ type(t2), optional :: x
+ end subroutine
+
+ ! bad, default initialization + allocatable
+ subroutine s2b (x) bind (c) ! { dg-error "BIND\\(C\\)" }
+ use m1
+ type(t2), allocatable, optional :: x
+ end subroutine
+
+ ! bad, default initialization + pointer
+ subroutine s2c (x) bind (c) ! { dg-error "BIND\\(C\\)" }
+ use m1
+ type(t2), pointer, optional :: x
+ end subroutine
+
+ ! Now do all the same tests without the optional attribute.
+
+ ! good, no default initialization, no pointer/allocatable attribute
+ subroutine s3a (x) bind (c)
+ use m1
+ type(t1) :: x
+ end subroutine
+
+ ! good, no default initialization
+ subroutine s3b (x) bind (c)
+ use m1
+ type(t1), allocatable :: x
+ end subroutine
+
+ ! good, no default initialization
+ subroutine s3c (x) bind (c)
+ use m1
+ type(t1), pointer :: x
+ end subroutine
+
+ ! good, default initialization but no pointer/allocatable attribute
+ subroutine s4a (x) bind (c)
+ use m1
+ type(t2) :: x
+ end subroutine
+
+ ! bad, default initialization + allocatable
+ subroutine s4b (x) bind (c) ! { dg-error "BIND\\(C\\)" }
+ use m1
+ type(t2), allocatable :: x
+ end subroutine
+
+ ! bad, default initialization + pointer
+ subroutine s4c (x) bind (c) ! { dg-error "BIND\\(C\\)" }
+ use m1
+ type(t2), pointer :: x
+ end subroutine
+
+ end interface
+end module
Index: Fortran/gfortran/regression/c-interop/c524a.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c524a.f90
@@ -0,0 +1,30 @@
+! { dg-do compile }
+! { dg-additional-options "-fcoarray=single" }
+!
+! TS 29113
+! C524a A coarray shall not be a dummy argument of a procedure that has
+! a proc-language-binding-spec.
+!
+! This file contains code that is expected to produce errors.
+
+module m
+
+ interface
+
+ ! No C binding, this should be OK.
+ subroutine s1 (x)
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT), codimension[*] :: x(:,:)
+ end subroutine
+
+ ! This one is bad.
+ subroutine s2 (x) bind (c) ! { dg-error "BIND\\(C\\)" }
+ use ISO_C_BINDING
+ implicit none
+ integer(C_INT), codimension[*] :: x(:,:)
+ end subroutine
+
+ end interface
+end module
+
Index: Fortran/gfortran/regression/c-interop/c535a-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535a-1.f90
@@ -0,0 +1,65 @@
+! { dg-do compile}
+!
+! TS 29113
+! C535a An assumed-rank entity shall be a dummy variable that does not
+! have the CODIMENSION or VALUE attribute.
+! An assumed-rank object may have the CONTIGUOUS attribute.
+!
+! This test file contains tests that are expected to all pass.
+
+! Check basic usage with no attributes.
+
+module m
+ type :: t
+ integer :: i
+ real :: f
+ end type
+end module
+
+subroutine s0 (a, b, c, d)
+ use m
+ implicit none
+ integer :: a(..)
+ real :: b(..)
+ type(t) :: c(..)
+ type(*) :: d(..)
+end subroutine
+
+! Likewise with dimension attribute.
+
+subroutine s1 (a, b, c, d)
+ use m
+ implicit none
+ integer, dimension(..) :: a
+ real, dimension(..) :: b
+ type(t), dimension(..) :: c
+ type(*), dimension(..) :: d
+end subroutine
+
+! Likewise with dimension statement.
+
+subroutine s2 (a, b, c, d)
+ use m
+ implicit none
+ integer :: a
+ real :: b
+ type(t) :: c
+ type(*) :: d
+ dimension a(..), b(..), c(..), d(..)
+end subroutine
+
+! Test that various other attributes are accepted.
+
+subroutine s3 (a, b, c, d, e, f, g, h, i, j)
+ implicit none
+ integer, allocatable :: a(..)
+ integer, asynchronous :: b(..)
+ integer, contiguous :: c(..)
+ integer, intent(in) :: d(..)
+ integer, intent(out) :: e(..)
+ integer, intent(inout) :: f(..)
+ integer, optional :: g(..)
+ integer, pointer :: h(..)
+ integer, target :: i(..)
+ integer, volatile :: j(..)
+end subroutine
Index: Fortran/gfortran/regression/c-interop/c535a-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535a-2.f90
@@ -0,0 +1,78 @@
+! { dg-do compile}
+! { dg-additional-options "-fcoarray=single" }
+!
+! TS 29113
+! C535a An assumed-rank entity shall be a dummy variable that does not
+! have the CODIMENSION or VALUE attribute.
+! An assumed-rank object may have the CONTIGUOUS attribute.
+!
+
+! This test file contains tests that are expected to issue diagnostics
+! for invalid code.
+
+! Check that diagnostics are issued when dimension(..) is used to declare
+! things that are not dummy variables.
+
+subroutine s0 (a)
+ implicit none
+ integer :: a
+
+ integer :: goodlocal
+ integer :: badlocal1(..) ! { dg-error "Assumed.rank" }
+ integer, dimension(..) :: badlocal2 ! { dg-error "Assumed.rank" }
+ integer :: badlocal3 ! { dg-error "Assumed.rank" }
+ dimension badlocal3(..)
+
+ integer :: goodcommon
+ integer :: badcommon1(..) ! { dg-error "Assumed.rank" }
+ integer, dimension(..) :: badcommon2 ! { dg-error "Assumed.rank" }
+ integer :: badcommon3 ! { dg-error "Assumed.rank" }
+ dimension badcommon3(..)
+ common /frob/ goodcommon, badcommon1, badcommon2, badcommon3
+
+ integer :: goodstatic
+ integer :: badstatic1(..) ! { dg-error "Assumed.rank" }
+ integer, dimension(..) :: badstatic2 ! { dg-error "Assumed.rank" }
+ integer :: badstatic3 ! { dg-error "Assumed.rank" }
+ dimension badstatic3(..)
+ save goodstatic, badstatic1, badstatic2, badstatic3
+
+ block
+ integer :: goodblocklocal
+ integer :: badblocklocal1(..) ! { dg-error "Assumed.rank" }
+ integer, dimension(..) :: badblocklocal2 ! { dg-error "Assumed.rank" }
+ integer :: badblocklocal3 ! { dg-error "Assumed.rank" }
+ dimension badblocklocal3(..)
+ end block
+
+end subroutine
+
+module m
+ integer :: goodmodvar
+ integer :: badmodvar1(..) ! { dg-error "Assumed.rank" }
+ integer, dimension(..) :: badmodvar2 ! { dg-error "Assumed.rank" }
+ integer :: badmodvar3 ! { dg-error "Assumed.rank" }
+ dimension badmodvar3(..)
+
+ save goodmodvar, badmodvar1, badmodvar2, badmodvar3
+
+ type :: t
+ integer :: goodcomponent
+ integer :: badcomponent1(..) ! { dg-error "must have an explicit shape" }
+ integer, dimension(..) :: badcomponent2 ! { dg-error "must have an explicit shape" }
+ end type
+end module
+
+! Check that diagnostics are issued when dimension(..) is used in combination
+! with the forbidden attributes.
+
+subroutine s2 (b) ! { dg-error "has no IMPLICIT type" }
+ implicit none
+ integer, codimension[*] :: b(..) ! { dg-error "assumed-rank array" }
+end subroutine
+
+subroutine s5 (e) ! { dg-error "has no IMPLICIT type" }
+ implicit none
+ integer, value :: e(..) ! { dg-error "VALUE attribute conflicts with DIMENSION" }
+end subroutine
+
Index: Fortran/gfortran/regression/c-interop/c535b-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535b-1.f90
@@ -0,0 +1,331 @@
+! { dg-do compile}
+! { dg-additional-options "-fcoarray=single" }
+!
+! TS 29113
+! C535b An assumed-rank variable name shall not appear in a designator
+! or expression except as an actual argument corresponding to a dummy
+! argument that is assumed-rank, the argument of the C_LOC function
+! in the ISO_C_BINDING intrinsic module, or the first argument in a
+! reference to an intrinsic inquiry function.
+!
+! This has been renamed C838 in the Fortran 2018 standard, with C_SIZEOF
+! and SELECT_RANK additionally added.
+!
+! This test file contains tests that are expected to all pass.
+
+! Check that passing an assumed-rank variable as an actual argument
+! corresponding to an assumed-rank dummy works.
+
+module m
+ interface
+ subroutine g (a, b)
+ implicit none
+ real :: a(..)
+ integer :: b
+ end subroutine
+ end interface
+end module
+
+subroutine s0 (x)
+ use m
+ implicit none
+ real :: x(..)
+
+ call g (x, 1)
+end subroutine
+
+! Check that calls to the permitted intrinsic functions work.
+
+function test_c_loc (a)
+ use iso_c_binding
+ implicit none
+ integer, target :: a(..)
+ type(c_ptr) :: test_c_loc
+
+ test_c_loc = c_loc (a)
+end function
+
+function test_allocated (a)
+ implicit none
+ integer, allocatable :: a(..)
+ logical :: test_allocated
+
+ test_allocated = allocated (a)
+end function
+
+! 2-argument forms of the associated intrinsic are tested in c535b-3.f90.
+function test_associated (a)
+ implicit none
+ integer, pointer :: a(..)
+ logical :: test_associated
+
+ test_associated = associated (a)
+end function
+
+function test_bit_size (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_bit_size
+
+ test_bit_size = bit_size (a)
+end function
+
+function test_digits (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_digits
+
+ test_digits = digits (a)
+end function
+
+function test_epsilon (a)
+ implicit none
+ real :: a(..)
+ real :: test_epsilon
+
+ test_epsilon = epsilon (a)
+end function
+
+function test_huge (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_huge
+
+ test_huge = huge (a)
+end function
+
+function test_is_contiguous (a)
+ implicit none
+ integer :: a(..)
+ logical :: test_is_contiguous
+
+ test_is_contiguous = is_contiguous (a)
+end function
+
+function test_kind (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_kind
+
+ test_kind = kind (a)
+end function
+
+function test_lbound (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_lbound
+
+ test_lbound = lbound (a, 1)
+end function
+
+function test_len1 (a)
+ implicit none
+ character(len=5) :: a(..)
+ integer :: test_len1
+
+ test_len1 = len (a)
+end function
+
+function test_len2 (a)
+ implicit none
+ character(len=*) :: a(..)
+ integer :: test_len2
+
+ test_len2 = len (a)
+end function
+
+function test_len3 (a)
+ implicit none
+ character(len=5), pointer :: a(..)
+ integer :: test_len3
+
+ test_len3 = len (a)
+end function
+
+function test_len4 (a)
+ implicit none
+ character(len=*), pointer :: a(..)
+ integer :: test_len4
+
+ test_len4 = len (a)
+end function
+
+function test_len5 (a)
+ implicit none
+ character(len=:), pointer :: a(..)
+ integer :: test_len5
+
+ test_len5 = len (a)
+end function
+
+function test_len6 (a)
+ implicit none
+ character(len=5), allocatable :: a(..)
+ integer :: test_len6
+
+ test_len6 = len (a)
+end function
+
+function test_len7 (a)
+ implicit none
+ character(len=*), allocatable :: a(..)
+ integer :: test_len7
+
+ test_len7 = len (a)
+end function
+
+function test_len8 (a)
+ implicit none
+ character(len=:), allocatable :: a(..)
+ integer :: test_len8
+
+ test_len8 = len (a)
+end function
+
+function test_maxexponent (a)
+ implicit none
+ real :: a(..)
+ integer :: test_maxexponent
+
+ test_maxexponent = maxexponent (a)
+end function
+
+function test_minexponent (a)
+ implicit none
+ real :: a(..)
+ integer :: test_minexponent
+
+ test_minexponent = minexponent (a)
+end function
+
+function test_new_line (a)
+ implicit none
+ character :: a(..)
+ character :: test_new_line
+
+ test_new_line = new_line (a)
+end function
+
+function test_precision (a)
+ implicit none
+ real :: a(..)
+ integer :: test_precision
+
+ test_precision = precision (a)
+end function
+
+function test_present (a, b, c)
+ implicit none
+ integer :: a, b
+ integer, optional :: c(..)
+ integer :: test_present
+
+ if (present (c)) then
+ test_present = a
+ else
+ test_present = b
+ end if
+end function
+
+function test_radix (a)
+ implicit none
+ real :: a(..)
+ integer :: test_radix
+
+ test_radix = radix (a)
+end function
+
+function test_range (a)
+ implicit none
+ real :: a(..)
+ integer :: test_range
+
+ test_range = range (a)
+end function
+
+function test_rank (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_rank
+
+ test_rank = rank (a)
+end function
+
+function test_shape (a)
+ implicit none
+ integer :: a(..)
+ logical :: test_shape
+
+ test_shape = (rank (a) .eq. size (shape (a)))
+end function
+
+function test_size (a)
+ implicit none
+ integer :: a(..)
+ logical :: test_size
+
+ test_size = (size (a) .eq. product (shape (a)))
+end function
+
+function test_storage_size (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_storage_size
+
+ test_storage_size = storage_size (a)
+end function
+
+function test_tiny (a)
+ implicit none
+ real :: a(..)
+ real :: test_tiny
+
+ test_tiny = tiny (a)
+end function
+
+function test_ubound (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_ubound
+
+ test_ubound = ubound (a, 1)
+end function
+
+! Note: there are no tests for these inquiry functions that can't
+! take an assumed-rank array argument for other reasons:
+!
+! coshape, lcobound, ucobound: requires CODIMENSION attribute, which is
+! not permitted on an assumed-rank variable.
+!
+
+! F2018 additionally permits the first arg to C_SIZEOF to be
+! assumed-rank (C838).
+
+function test_c_sizeof (a)
+ use iso_c_binding
+ implicit none
+ integer :: a(..)
+ integer :: test_c_sizeof
+
+ test_c_sizeof = c_sizeof (a)
+end function
+
+! F2018 additionally permits an assumed-rank array as the selector
+! in a SELECT RANK construct (C838).
+
+function test_select_rank (a)
+ implicit none
+ integer :: a(..)
+ integer :: test_select_rank
+
+ select rank (a)
+ rank (0)
+ test_select_rank = 0
+ rank (1)
+ test_select_rank = 1
+ rank (2)
+ test_select_rank = 2
+ rank default
+ test_select_rank = -1
+ end select
+end function
Index: Fortran/gfortran/regression/c-interop/c535b-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535b-2.f90
@@ -0,0 +1,386 @@
+! PR 101334
+! PR 101337
+! { dg-do compile}
+! { dg-additional-options "-fcoarray=single" }
+!
+! TS 29113
+! C535b An assumed-rank variable name shall not appear in a designator
+! or expression except as an actual argument corresponding to a dummy
+! argument that is assumed-rank, the argument of the C_LOC function
+! in the ISO_C_BINDING intrinsic module, or the first argument in a
+! reference to an intrinsic inquiry function.
+!
+! This has been renamed C838 in the Fortran 2018 standard, with C_SIZEOF
+! and SELECT_RANK additionally added.
+!
+! This test file contains tests that are expected to issue diagnostics
+! for invalid code.
+
+! Check that passing an assumed-rank variable as an actual argument
+! corresponding to a non-assumed-rank dummy gives a diagnostic.
+
+module m
+ interface
+ subroutine f (a, b)
+ implicit none
+ integer :: a
+ integer :: b
+ end subroutine
+ subroutine g (a, b)
+ implicit none
+ integer :: a(..)
+ integer :: b(..)
+ end subroutine
+ subroutine h (a, b)
+ implicit none
+ integer :: a(*)
+ integer :: b(*)
+ end subroutine
+ subroutine i (a, b)
+ implicit none
+ integer :: a(:)
+ integer :: b(:)
+ end subroutine
+ subroutine j (a, b)
+ implicit none
+ integer :: a(3,3)
+ integer :: b(3,3)
+ end subroutine
+ end interface
+end module
+
+subroutine test_calls (x, y)
+ use m
+ implicit none
+ integer :: x(..), y(..)
+
+ ! Make sure each invalid argument produces a diagnostic.
+ ! scalar dummies
+ call f (x, & ! { dg-error "(A|a)ssumed.rank" }
+ y) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ ! assumed-rank dummies
+ call g (x, y) ! OK
+ ! assumed-size dummies
+ call h (x, & ! { dg-error "(A|a)ssumed.rank" "pr101334" }
+ y) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ ! assumed-shape dummies
+ call i (x, & ! { dg-error "(A|a)ssumed.rank" }
+ y) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ ! fixed-size array dummies
+ call j (x, & ! { dg-error "(A|a)ssumed.rank" "pr101334" }
+ y) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+end subroutine
+
+! Check that you can't use an assumed-rank array variable in an array
+! element or section designator.
+
+subroutine test_designators (x)
+ use m
+ implicit none
+ integer :: x(..)
+
+ call f (x(1), 1) ! { dg-error "(A|a)ssumed.rank" }
+ call g (x(1:3:1), & ! { dg-error "(A|a)ssumed.rank" }
+ x)
+end subroutine
+
+! Check that you can't use an assumed-rank array variable in elemental
+! expressions. Make sure binary operators produce the error for either or
+! both operands.
+
+subroutine test_expressions (a, b, c, l, m, n, x, y, z, p, q, r, s, i, j)
+ implicit none
+ integer :: a(..), b(..), c(..)
+ logical :: l(..), m(..), n(..)
+ integer :: x(s), y(s), z(s)
+ logical :: p(s), q(s), r(s)
+ integer :: s
+ integer :: i
+ logical :: j
+
+ ! Assignment
+
+ z = x ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a ! { dg-error "(A|a)ssumed.rank" }
+ z = i ! OK
+ c = i ! { dg-error "(A|a)ssumed.rank" }
+
+ r = p ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l ! { dg-error "(A|a)ssumed.rank" }
+ r = j ! OK
+ n = j ! { dg-error "(A|a)ssumed.rank" }
+
+ ! Arithmetic
+
+ z = -x ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = -a ! { dg-error "(A|a)ssumed.rank" }
+ z = -i ! OK
+ c = -i ! { dg-error "(A|a)ssumed.rank" }
+
+ z = x + y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ + b ! { dg-error "(A|a)ssumed.rank" }
+ z = x + i ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a + i ! { dg-error "(A|a)ssumed.rank" }
+ z = i + y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = i + b ! { dg-error "(A|a)ssumed.rank" }
+
+ z = x - y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ - b ! { dg-error "(A|a)ssumed.rank" }
+ z = x - i ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a - i ! { dg-error "(A|a)ssumed.rank" }
+ z = i - y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = i - b ! { dg-error "(A|a)ssumed.rank" }
+
+ z = x * y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ * b ! { dg-error "(A|a)ssumed.rank" }
+ z = x * i ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a * i ! { dg-error "(A|a)ssumed.rank" }
+ z = i * y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = i * b ! { dg-error "(A|a)ssumed.rank" }
+
+ z = x / y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ / b ! { dg-error "(A|a)ssumed.rank" }
+ z = x / i ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a / i ! { dg-error "(A|a)ssumed.rank" }
+ z = i / y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = i / b ! { dg-error "(A|a)ssumed.rank" }
+
+ z = x ** y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ ** b ! { dg-error "(A|a)ssumed.rank" }
+ z = x ** i ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = a ** i ! { dg-error "(A|a)ssumed.rank" }
+ z = i ** y ! OK
+ c & ! { dg-error "(A|a)ssumed.rank" }
+ = i ** b ! { dg-error "(A|a)ssumed.rank" }
+
+ ! Comparisons
+
+ r = x .eq. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .eq. b ! { dg-error "(A|a)ssumed.rank" }
+ r = x .eq. i ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a .eq. i ! { dg-error "(A|a)ssumed.rank" }
+ r = i .eq. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = i .eq. b ! { dg-error "(A|a)ssumed.rank" }
+
+ r = x .ne. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .ne. b ! { dg-error "(A|a)ssumed.rank" }
+ r = x .ne. i ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a .ne. i ! { dg-error "(A|a)ssumed.rank" }
+ r = i .ne. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = i .ne. b ! { dg-error "(A|a)ssumed.rank" }
+
+ r = x .lt. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .lt. b ! { dg-error "(A|a)ssumed.rank" }
+ r = x .lt. i ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a .lt. i ! { dg-error "(A|a)ssumed.rank" }
+ r = i .lt. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = i .lt. b ! { dg-error "(A|a)ssumed.rank" }
+
+ r = x .le. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .le. b ! { dg-error "(A|a)ssumed.rank" }
+ r = x .le. i ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a .le. i ! { dg-error "(A|a)ssumed.rank" }
+ r = i .le. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = i .le. b ! { dg-error "(A|a)ssumed.rank" }
+
+ r = x .gt. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .gt. b ! { dg-error "(A|a)ssumed.rank" }
+ r = x .gt. i ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a .gt. i ! { dg-error "(A|a)ssumed.rank" }
+ r = i .gt. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = i .gt. b ! { dg-error "(A|a)ssumed.rank" }
+
+ r = x .ge. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .ge. b ! { dg-error "(A|a)ssumed.rank" }
+ r = x .ge. i ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = a .ge. i ! { dg-error "(A|a)ssumed.rank" }
+ r = i .ge. y ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = i .ge. b ! { dg-error "(A|a)ssumed.rank" }
+
+ ! Logical operators
+
+ r = .not. p ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = .not. l ! { dg-error "(A|a)ssumed.rank" }
+ r = .not. j ! OK
+ n = .not. j ! { dg-error "(A|a)ssumed.rank" }
+
+ r = p .and. q ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .and. m ! { dg-error "(A|a)ssumed.rank" }
+ r = p .and. j ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l .and. j ! { dg-error "(A|a)ssumed.rank" }
+ r = j .and. q ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = j .and. m ! { dg-error "(A|a)ssumed.rank" }
+
+ r = p .or. q ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .or. m ! { dg-error "(A|a)ssumed.rank" }
+ r = p .or. j ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l .or. j ! { dg-error "(A|a)ssumed.rank" }
+ r = j .or. q ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = j .or. m ! { dg-error "(A|a)ssumed.rank" }
+
+ r = p .eqv. q ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .eqv. m ! { dg-error "(A|a)ssumed.rank" }
+ r = p .eqv. j ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l .eqv. j ! { dg-error "(A|a)ssumed.rank" }
+ r = j .eqv. q ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = j .eqv. m ! { dg-error "(A|a)ssumed.rank" }
+
+ r = p .neqv. q ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l & ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ .neqv. m ! { dg-error "(A|a)ssumed.rank" }
+ r = p .neqv. j ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = l .neqv. j ! { dg-error "(A|a)ssumed.rank" }
+ r = j .neqv. q ! OK
+ n & ! { dg-error "(A|a)ssumed.rank" }
+ = j .neqv. m ! { dg-error "(A|a)ssumed.rank" }
+
+end subroutine
+
+! Check that calls to disallowed intrinsic functions produce a diagnostic.
+! There are 100+ "elemental" intrinsics defined in the standard, and
+! 25+ "transformational" intrinsics that accept array operands, and that
+! doesn't include intrinsics in the standard modules. To keep the length of
+! this test to something sane, check only a handful of these functions on
+! the theory that related functions are probably implemented similarly and
+! probably share the same argument-processing code.
+
+subroutine test_intrinsics (i1, i2, r1, r2, c1, c2, l1, l2, s1, s2)
+ implicit none
+ integer :: i1(..), i2(..)
+ real :: r1(..), r2(..)
+ complex :: c1(..), c2(..)
+ logical :: l1(..), l2(..)
+ character :: s1(..), s2(..)
+
+ integer :: i
+ real :: r
+ logical :: l
+
+ ! trig, hyperbolic, other math functions
+ r1 & ! { dg-error "(A|a)ssumed.rank" }
+ = atan2 (r1, & ! { dg-error "(A|a)ssumed.rank" }
+ r2) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ r1 & ! { dg-error "(A|a)ssumed.rank" }
+ = atan (r2) ! { dg-error "(A|a)ssumed.rank" }
+ c1 & ! { dg-error "(A|a)ssumed.rank" }
+ = atan (c2) ! { dg-error "(A|a)ssumed.rank" }
+ r1 & ! { dg-error "(A|a)ssumed.rank" }
+ = cos (r2) ! { dg-error "(A|a)ssumed.rank" }
+ r1 & ! { dg-error "(A|a)ssumed.rank" }
+ = exp (r2) ! { dg-error "(A|a)ssumed.rank" }
+ r1 & ! { dg-error "(A|a)ssumed.rank" }
+ = sinh (r2) ! { dg-error "(A|a)ssumed.rank" }
+
+ ! bit operations
+ l1 & ! { dg-error "(A|a)ssumed.rank" }
+ = blt (i1, & ! { dg-error "(A|a)ssumed.rank" }
+ i2) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ l1 & ! { dg-error "(A|a)ssumed.rank" }
+ = btest (i1, 0) ! { dg-error "(A|a)ssumed.rank" }
+ i1 & ! { dg-error "(A|a)ssumed.rank" }
+ = not (i2) ! { dg-error "(A|a)ssumed.rank" }
+ i1 & ! { dg-error "(A|a)ssumed.rank" }
+ = popcnt (i2) ! { dg-error "(A|a)ssumed.rank" }
+
+ ! type conversions
+ s1 & ! { dg-error "(A|a)ssumed.rank" }
+ = char (i1) ! { dg-error "(A|a)ssumed.rank" }
+ c1 & ! { dg-error "(A|a)ssumed.rank" }
+ = cmplx (r1, & ! { dg-error "(A|a)ssumed.rank" }
+ r2) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ i1 & ! { dg-error "(A|a)ssumed.rank" }
+ = floor (r1) ! { dg-error "(A|a)ssumed.rank" }
+ r1 & ! { dg-error "(A|a)ssumed.rank" }
+ = real (c1) ! { dg-error "(A|a)ssumed.rank" }
+
+ ! reductions
+ l = any (l2) ! { dg-error "(A|a)ssumed.rank" }
+ r = dot_product (r1, & ! { dg-error "(A|a)ssumed.rank" }
+ r2) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ i = iall (i2, & ! { dg-error "(A|a)ssumed.rank" }
+ l2) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+
+ ! string operations
+ s1 & ! { dg-error "(A|a)ssumed.rank" }
+ = adjustr (s2) ! { dg-error "(A|a)ssumed.rank" }
+ i1 & ! { dg-error "(A|a)ssumed.rank" }
+ = index (c1, & ! { dg-error "(A|a)ssumed.rank" }
+ c2) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+
+ ! misc
+ i1 & ! { dg-error "(A|a)ssumed.rank" }
+ = cshift (i2, 4) ! { dg-error "(A|a)ssumed.rank" }
+ i = findloc (r1, 0.0) ! { dg-error "(A|a)ssumed.rank" }
+ r1 & ! { dg-error "(A|a)ssumed.rank" }
+ = matmul (r1, & ! { dg-error "(A|a)ssumed.rank" }
+ r2) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ r1 & ! { dg-error "(A|a)ssumed.rank" }
+ = reshape (r2, [10, 3]) ! { dg-error "(A|a)ssumed.rank" }
+ i1 & ! { dg-error "(A|a)ssumed.rank" }
+ = sign (i1, & ! { dg-error "(A|a)ssumed.rank" }
+ i2) ! { dg-error "(A|a)ssumed.rank" "pr101337" }
+ s1 & ! { dg-error "(A|a)ssumed.rank" }
+ = transpose (s2) ! { dg-error "(A|a)ssumed.rank" }
+
+end subroutine
Index: Fortran/gfortran/regression/c-interop/c535b-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535b-3.f90
@@ -0,0 +1,79 @@
+! PR 101334
+! { dg-do compile}
+! { dg-additional-options "-fcoarray=single" }
+!
+! TS 29113
+! C535b An assumed-rank variable name shall not appear in a designator
+! or expression except as an actual argument corresponding to a dummy
+! argument that is assumed-rank, the argument of the C_LOC function
+! in the ISO_C_BINDING intrinsic module, or the first argument in a
+! reference to an intrinsic inquiry function.
+!
+! This has been renamed C838 in the Fortran 2018 standard, with C_SIZEOF
+! and SELECT_RANK additionally added.
+!
+! This tests various forms of the 2-argument associated intrinsic.
+
+function test_associated2 (a, b)
+ implicit none
+ integer, pointer :: a(..)
+ integer, target :: b(..)
+ logical :: test_associated2
+
+ test_associated2 = associated (a, b) ! { dg-error "Assumed.rank" }
+end function
+
+function test_associated3 (a, b)
+ implicit none
+ integer, pointer :: a(..)
+ integer, target :: b
+ logical :: test_associated3
+
+ test_associated3 = associated (a, b) ! { dg-bogus "must be of rank -1" "pr101334" }
+end function
+
+function test_associated4 (a, b)
+ implicit none
+ integer, pointer :: a(..)
+ integer, target :: b(:)
+ logical :: test_associated4
+
+ test_associated4 = associated (a, b) ! { dg-bogus "must be of rank -1" "pr101334" }
+end function
+
+function test_associated5 (a, b)
+ implicit none
+ integer, pointer :: a(..)
+ integer, target :: b(20)
+ logical :: test_associated5
+
+ test_associated5 = associated (a, b) ! { dg-bogus "must be of rank -1" "pr101334" }
+end function
+
+function test_associated6 (a, b)
+ implicit none
+ integer, pointer :: a(..)
+ integer, pointer :: b(..)
+ logical :: test_associated6
+
+ test_associated6 = associated (a, b) ! { dg-error "Assumed.rank" }
+end function
+
+function test_associated7 (a, b)
+ implicit none
+ integer, pointer :: a(..)
+ integer, pointer :: b
+ logical :: test_associated7
+
+ test_associated7 = associated (a, b) ! { dg-bogus "must be of rank -1" "pr101334" }
+end function
+
+function test_associated8 (a, b)
+ implicit none
+ integer, pointer :: a(..)
+ integer, pointer :: b(:)
+ logical :: test_associated8
+
+ test_associated8 = associated (a, b) ! { dg-bogus "must be of rank -1" "pr101334" }
+end function
+
Index: Fortran/gfortran/regression/c-interop/c535c-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535c-1.f90
@@ -0,0 +1,164 @@
+! PR 54753
+! { dg-do compile}
+!
+! TS 29113
+! C535c If an assumed-size or nonallocatable nonpointer assumed-rank
+! array is an actual argument corresponding to a dummy argument that
+! is an INTENT(OUT) assumed-rank array, it shall not be polymorphic, [...].
+!
+! This constraint is numbered C839 in the Fortran 2018 standard.
+!
+! This test file contains tests that are expected to issue diagnostics
+! for invalid code.
+
+module t
+ type :: t1
+ integer :: id
+ real :: xyz(3)
+ end type
+end module
+
+module m
+ use t
+
+ ! Assumed-type dummies are (unlimited) polymorphic too, but F2018:C709
+ ! already prohibits them from being declared intent(out). So we only
+ ! test dummies of class type that are polymorphic or unlimited
+ ! polymorphic.
+ interface
+ subroutine poly (x, y)
+ use t
+ class(t1) :: x(..)
+ class(t1), intent (out) :: y(..)
+ end subroutine
+ subroutine upoly (x, y)
+ class(*) :: x(..)
+ class(*), intent (out) :: y(..)
+ end subroutine
+ end interface
+
+contains
+
+ ! The known-size calls should all be OK as they do not involve
+ ! assumed-size or assumed-rank actual arguments.
+ subroutine test_known_size_nonpolymorphic (a1, a2, n)
+ integer :: n
+ type(t1) :: a1(n,n), a2(n)
+ call poly (a1, a2)
+ call upoly (a1, a2)
+ end subroutine
+ subroutine test_known_size_polymorphic (a1, a2, n)
+ integer :: n
+ class(t1) :: a1(n,n), a2(n)
+ call poly (a1, a2)
+ call upoly (a1, a2)
+ end subroutine
+ subroutine test_known_size_unlimited_polymorphic (a1, a2, n)
+ integer :: n
+ class(*) :: a1(n,n), a2(n)
+ call upoly (a1, a2)
+ end subroutine
+
+ ! Likewise passing a scalar as the assumed-rank argument.
+ subroutine test_scalar_nonpolymorphic (a1, a2)
+ type(t1) :: a1, a2
+ call poly (a1, a2)
+ call upoly (a1, a2)
+ end subroutine
+ subroutine test_scalar_polymorphic (a1, a2)
+ class(t1) :: a1, a2
+ call poly (a1, a2)
+ call upoly (a1, a2)
+ end subroutine
+ subroutine test_scalar_unlimited_polymorphic (a1, a2)
+ class(*) :: a1, a2
+ call upoly (a1, a2)
+ end subroutine
+
+ ! The polymorphic cases for assumed-size are bad.
+ subroutine test_assumed_size_nonpolymorphic (a1, a2)
+ type(t1) :: a1(*), a2(*)
+ call poly (a1, a2) ! OK
+ call upoly (a1, a2) ! OK
+ end subroutine
+ subroutine test_assumed_size_polymorphic (a1, a2)
+ class(t1) :: a1(*), a2(*)
+ call poly (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ call upoly (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ call poly (a1(5), a2(4:7))
+ end subroutine
+ subroutine test_assumed_size_unlimited_polymorphic (a1, a2)
+ class(*) :: a1(*), a2(*)
+ call upoly (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+
+ ! The arguments being passed to poly/upoly in this set are *not*
+ ! assumed size and should not error.
+ subroutine test_not_assumed_size_nonpolymorphic (a1, a2)
+ type(t1) :: a1(*), a2(*)
+ call poly (a1(5), a2(4:7))
+ call upoly (a1(5), a2(4:7))
+ call poly (a1(:10), a2(:-5))
+ call upoly (a1(:10), a2(:-5))
+ end subroutine
+ subroutine test_not_assumed_size_polymorphic (a1, a2)
+ class(t1) :: a1(*), a2(*)
+ call poly (a1(5), a2(4:7))
+ call upoly (a1(5), a2(4:7))
+ call poly (a1(:10), a2(:-5))
+ call upoly (a1(:10), a2(:-5))
+ end subroutine
+ subroutine test_not_assumed_size_unlimited_polymorphic (a1, a2)
+ class(*) :: a1(*), a2(*)
+ call upoly (a1(5), a2(4:7))
+ call upoly (a1(:10), a2(:-5))
+ end subroutine
+
+ ! Polymorphic assumed-rank without pointer/allocatable is also bad.
+ subroutine test_assumed_rank_nonpolymorphic (a1, a2)
+ type(t1) :: a1(..), a2(..)
+ call poly (a1, a2) ! OK
+ call upoly (a1, a2) ! OK
+ end subroutine
+ subroutine test_assumed_rank_polymorphic (a1, a2)
+ class(t1) :: a1(..), a2(..)
+ call poly (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ call upoly (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+ subroutine test_assumed_rank_unlimited_polymorphic (a1, a2)
+ class(*) :: a1(..), a2(..)
+ call upoly (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+
+ ! Pointer/allocatable assumed-rank should be OK.
+ subroutine test_pointer_nonpolymorphic (a1, a2)
+ type(t1), pointer :: a1(..), a2(..)
+ call poly (a1, a2)
+ call upoly (a1, a2)
+ end subroutine
+ subroutine test_pointer_polymorphic (a1, a2)
+ class(t1), pointer :: a1(..), a2(..)
+ call poly (a1, a2)
+ call upoly (a1, a2)
+ end subroutine
+ subroutine test_pointer_unlimited_polymorphic (a1, a2)
+ class(*), pointer :: a1(..), a2(..)
+ call upoly (a1, a2)
+ end subroutine
+
+ subroutine test_allocatable_nonpolymorphic (a1, a2)
+ type(t1), allocatable :: a1(..), a2(..)
+ call poly (a1, a2)
+ call upoly (a1, a2)
+ end subroutine
+ subroutine test_allocatable_polymorphic (a1, a2)
+ class(t1), allocatable :: a1(..), a2(..)
+ call poly (a1, a2)
+ call upoly (a1, a2)
+ end subroutine
+ subroutine test_allocatable_unlimited_polymorphic (a1, a2)
+ class(*), allocatable :: a1(..), a2(..)
+ call upoly (a1, a2)
+ end subroutine
+
+end module
Index: Fortran/gfortran/regression/c-interop/c535c-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535c-2.f90
@@ -0,0 +1,74 @@
+! PR 54753
+! { dg-do compile}
+!
+! TS 29113
+! C535c If an assumed-size or nonallocatable nonpointer assumed-rank
+! array is an actual argument corresponding to a dummy argument that
+! is an INTENT(OUT) assumed-rank array, it shall not be [...]
+! finalizable [...].
+!
+! This constraint is numbered C839 in the Fortran 2018 standard.
+!
+! This test file contains tests that are expected to issue diagnostics
+! for invalid code.
+
+module m
+
+ type :: t1
+ integer :: id
+ real :: xyz(3)
+ contains
+ final :: finalize_t1
+ end type
+
+contains
+
+ subroutine finalize_t1 (obj)
+ type(t1) :: obj
+ end subroutine
+
+ subroutine s1 (x, y)
+ type(t1) :: x(..)
+ type(t1), intent(out) :: y(..)
+ end subroutine
+
+ ! This call should be OK as it does not involve assumed-size or
+ ! assumed-rank actual arguments.
+ subroutine test_known_size (a1, a2, n)
+ integer :: n
+ type(t1) :: a1(n,n), a2(n)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! Calls with an assumed-size array argument should be rejected.
+ subroutine test_assumed_size (a1, a2)
+ type(t1) :: a1(*), a2(*)
+
+ call s1 (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+
+ ! This call should be OK.
+ subroutine test_assumed_rank_pointer (a1, a2)
+ type(t1), pointer :: a1(..), a2(..)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! This call should be OK.
+ subroutine test_assumed_rank_allocatable (a1, a2)
+ type(t1), allocatable :: a1(..), a2(..)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! The call should be rejected with a nonallocatable nonpointer
+ ! assumed-rank actual argument.
+ subroutine test_assumed_rank_plain (a1, a2)
+ type(t1) :: a1(..), a2(..)
+
+ call s1 (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+
+end module
+
Index: Fortran/gfortran/regression/c-interop/c535c-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535c-3.f90
@@ -0,0 +1,72 @@
+! PR 54753
+! { dg-do compile }
+!
+! TS 29113
+! C535c If an assumed-size or nonallocatable nonpointer assumed-rank
+! array is an actual argument corresponding to a dummy argument that
+! is an INTENT(OUT) assumed-rank array, it shall not be [...]
+! of a type with an allocatable ultimate component [...].
+!
+! This constraint is numbered C839 in the Fortran 2018 standard.
+!
+! This test file contains tests that are expected to issue diagnostics
+! for invalid code.
+
+module m
+
+ type :: t1
+ integer :: id
+ real :: xyz(3)
+ character, allocatable :: notes
+ end type
+
+contains
+
+ subroutine finalize_t1 (obj)
+ type(t1) :: obj
+ end subroutine
+
+ subroutine s1 (x, y)
+ type(t1) :: x(..)
+ type(t1), intent(out) :: y(..)
+ end subroutine
+
+ ! This call should be OK as it does not involve assumed-size or
+ ! assumed-rank actual arguments.
+ subroutine test_known_size (a1, a2, n)
+ integer :: n
+ type(t1) :: a1(n,n), a2(n)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! Calls with an assumed-size array argument should be rejected.
+ subroutine test_assumed_size (a1, a2)
+ type(t1) :: a1(*), a2(*)
+
+ call s1 (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+
+ ! This call should be OK.
+ subroutine test_assumed_rank_pointer (a1, a2)
+ type(t1), pointer :: a1(..), a2(..)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! This call should be OK.
+ subroutine test_assumed_rank_allocatable (a1, a2)
+ type(t1), allocatable :: a1(..), a2(..)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! The call should be rejected with a nonallocatable nonpointer
+ ! assumed-rank actual argument.
+ subroutine test_assumed_rank_plain (a1, a2)
+ type(t1) :: a1(..), a2(..)
+
+ call s1 (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+
+end module
Index: Fortran/gfortran/regression/c-interop/c535c-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/c535c-4.f90
@@ -0,0 +1,72 @@
+! PR 54753
+! { dg-do compile }
+!
+! TS 29113
+! C535c If an assumed-size or nonallocatable nonpointer assumed-rank
+! array is an actual argument corresponding to a dummy argument that
+! is an INTENT(OUT) assumed-rank array, it shall not be [...]
+! of a type for which default initialization is specified.
+!
+! This constraint is numbered C839 in the Fortran 2018 standard.
+!
+! This test file contains tests that are expected to issue diagnostics
+! for invalid code.
+
+module m
+
+ type :: t1
+ integer :: id
+ real :: xyz(3)
+ integer :: tag = -1
+ end type
+
+contains
+
+ subroutine finalize_t1 (obj)
+ type(t1) :: obj
+ end subroutine
+
+ subroutine s1 (x, y)
+ type(t1) :: x(..)
+ type(t1), intent(out) :: y(..)
+ end subroutine
+
+ ! This call should be OK as it does not involve assumed-size or
+ ! assumed-rank actual arguments.
+ subroutine test_known_size (a1, a2, n)
+ integer :: n
+ type(t1) :: a1(n,n), a2(n)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! Calls with an assumed-size array argument should be rejected.
+ subroutine test_assumed_size (a1, a2)
+ type(t1) :: a1(*), a2(*)
+
+ call s1 (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+
+ ! This call should be OK.
+ subroutine test_assumed_rank_pointer (a1, a2)
+ type(t1), pointer :: a1(..), a2(..)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! This call should be OK.
+ subroutine test_assumed_rank_allocatable (a1, a2)
+ type(t1), allocatable :: a1(..), a2(..)
+
+ call s1 (a1, a2)
+ end subroutine
+
+ ! The call should be rejected with a nonallocatable nonpointer
+ ! assumed-rank actual argument.
+ subroutine test_assumed_rank_plain (a1, a2)
+ type(t1) :: a1(..), a2(..)
+
+ call s1 (a1, a2) ! { dg-error "(A|a)ssumed.rank" }
+ end subroutine
+
+end module
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-1-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-1-c.c
@@ -0,0 +1,91 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+extern void ftest (CFI_cdesc_t *a, CFI_cdesc_t *b);
+
+struct m {
+ int i;
+ int j;
+};
+
+#define imax 10
+#define jmax 5
+
+void
+ctest (CFI_cdesc_t *a)
+{
+
+ struct m bdata[imax][jmax];
+ CFI_CDESC_T(2) bdesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+ int i, j;
+ CFI_index_t subscripts[2];
+ struct m* mp;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != imax)
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != jmax)
+ abort ();
+
+ /* Transpose a's contents into bdata. */
+ for (j = 0; j < jmax; j++)
+ {
+ subscripts[1] = j;
+ for (i = 0; i < imax; i++)
+ {
+ subscripts[0] = i;
+ mp = (struct m *) CFI_address (a, subscripts);
+ if (mp->i != i + 1)
+ abort ();
+ if (mp->j != j + 1)
+ abort ();
+ bdata[i][j].i = mp->i;
+ bdata[i][j].j = mp->j;
+ }
+ }
+
+ /* Fill in bdesc. */
+ subscripts[0] = jmax;
+ subscripts[1] = imax;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, bdata, CFI_attribute_other,
+ CFI_type_struct,
+ sizeof (struct m), 2, subscripts));
+
+ /* Sanity checking to make sure the descriptor has been initialized
+ properly. */
+ dump_CFI_cdesc_t (b);
+ if (b->version != CFI_VERSION)
+ abort ();
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_other)
+ abort ();
+ if (b->dim[0].lower_bound != 0)
+ abort ();
+ if (b->dim[0].extent != jmax)
+ abort ();
+ if (b->dim[1].lower_bound != 0)
+ abort ();
+ if (b->dim[1].extent != imax)
+ abort ();
+
+ /* Call back into Fortran, passing both the a and b arrays. */
+ ftest (a, b);
+}
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-1.f90
@@ -0,0 +1,66 @@
+! { dg-do run }
+! { dg-additional-sources "cf-descriptor-1-c.c dump-descriptors.c" }
+!
+! This program checks that building a descriptor for a fixed-size array
+! in C works and that you can use it to call back into a Fortran function
+! declared to have c binding, as an assumed-shape argument.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+subroutine ftest (a, b) bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:), b(:,:)
+ integer :: i, j
+
+ if (size (a,1) .ne. imax) stop 101
+ if (size (a,2) .ne. jmax) stop 102
+ if (size (b,1) .ne. jmax) stop 103
+ if (size (b,2) .ne. imax) stop 104
+
+ do j = 1, jmax
+ do i = 1, imax
+ if (a(i,j)%i .ne. i) stop 201
+ if (a(i,j)%j .ne. j) stop 202
+ if (b(j,i)%i .ne. i) stop 203
+ if (b(j,i)%j .ne. j) stop 204
+ end do
+ end do
+end subroutine
+
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ end subroutine
+ end interface
+
+ type(m) :: aa(imax,jmax)
+ integer :: i, j
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ end do
+ end do
+
+ ! Pass the initialized array to a C function ctest, which will generate its
+ ! transpose and call ftest with it.
+
+ call ctest (aa)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-2-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-2-c.c
@@ -0,0 +1,91 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+extern void ftest (CFI_cdesc_t *a, CFI_cdesc_t *b);
+
+struct m {
+ int i;
+ int j;
+};
+
+#define imax 10
+#define jmax 5
+
+void
+ctest (CFI_cdesc_t *a)
+{
+
+ struct m bdata[imax][jmax];
+ CFI_CDESC_T(2) bdesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+ int i, j;
+ CFI_index_t subscripts[2];
+ struct m* mp;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != imax)
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != jmax)
+ abort ();
+
+ /* Transpose a's contents into bdata. */
+ for (j = 0; j < jmax; j++)
+ {
+ subscripts[1] = j;
+ for (i = 0; i < imax; i++)
+ {
+ subscripts[0] = i;
+ mp = (struct m *) CFI_address (a, subscripts);
+ if (mp->i != i + 1)
+ abort ();
+ if (mp->j != j + 1)
+ abort ();
+ bdata[i][j].i = mp->i;
+ bdata[i][j].j = mp->j;
+ }
+ }
+
+ /* Fill in bdesc. */
+ subscripts[0] = jmax;
+ subscripts[1] = imax;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, bdata, CFI_attribute_other,
+ CFI_type_struct,
+ sizeof (struct m), 2, subscripts));
+
+ /* Sanity checking to make sure the descriptor has been initialized
+ properly. */
+ dump_CFI_cdesc_t (b);
+ if (b->version != CFI_VERSION)
+ abort ();
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_other)
+ abort ();
+ if (b->dim[0].lower_bound != 0)
+ abort ();
+ if (b->dim[0].extent != jmax)
+ abort ();
+ if (b->dim[1].lower_bound != 0)
+ abort ();
+ if (b->dim[1].extent != imax)
+ abort ();
+
+ /* Call back into Fortran, passing both the a and b arrays. */
+ ftest (a, b);
+}
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-2.f90
@@ -0,0 +1,82 @@
+! PR 93308
+! { dg-do run }
+! { dg-additional-sources "cf-descriptor-2-c.c dump-descriptors.c" }
+!
+! This program checks that building a descriptor for a fixed-size array
+! in C works and that you can use it to call back into a Fortran function
+! declared to have c binding, as an assumed-rank argument.
+!
+! Fixed by
+! https://gcc.gnu.org/pipermail/gcc-patches/2021-June/572725.html
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+subroutine ftest (a, b) bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ type(m) :: a(..), b(..)
+ integer :: i, j
+
+ select rank (a)
+ rank (2)
+ select rank (b)
+ rank (2)
+ ! print *, lbound(a,1), ubound(a,1), lbound(a,2), ubound(a,2)
+ ! print *, lbound(b,1), ubound(b,1), lbound(b,2), ubound(b,2)
+ if (lbound (a,1) .ne. 1 .or. ubound (a,1) .ne. imax) stop 101
+ if (lbound (a,2) .ne. 1 .or. ubound (a,2) .ne. jmax) stop 102
+ if (lbound (b,1) .ne. 1 .or. ubound (b,1) .ne. jmax) stop 103
+ if (lbound (b,2) .ne. 1 .or. ubound (b,2) .ne. imax) stop 104
+ do j = 1, jmax
+ do i = 1, imax
+ print *, a(i,j)%i, a(i,j)%j, b(j,i)%i, b(j,i)%j
+ if (a(i,j)%i .ne. i) stop 105
+ if (a(i,j)%j .ne. j) stop 106
+ if (b(j,i)%i .ne. i) stop 107
+ if (b(j,i)%j .ne. j) stop 108
+ end do
+ end do
+ rank default
+ stop 106
+ end select
+ rank default
+ stop 107
+ end select
+end subroutine
+
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ end subroutine
+ end interface
+
+ type(m) :: aa(imax,jmax)
+ integer :: i, j
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ end do
+ end do
+
+ ! Pass the initialized array to a C function ctest, which will generate its
+ ! transpose and call ftest with it.
+
+ call ctest (aa)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-3-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-3-c.c
@@ -0,0 +1,92 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (int imagic, int jmagic);
+extern void ftest (CFI_cdesc_t *a, CFI_cdesc_t *b, int initp);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest (int imagic, int jmagic)
+{
+ CFI_CDESC_T(0) adesc;
+ CFI_CDESC_T(0) bdesc;
+ CFI_cdesc_t *a = (CFI_cdesc_t *) &adesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+ struct m* mp;
+
+ /* Create the descriptor for a, then sanity-check it. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (a, NULL, CFI_attribute_allocatable,
+ CFI_type_struct,
+ sizeof (struct m), 0, NULL));
+ dump_CFI_cdesc_t (a);
+ if (a->version != CFI_VERSION)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof (struct m))
+ abort ();
+
+ /* Likewise for b. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, NULL, CFI_attribute_pointer,
+ CFI_type_struct,
+ sizeof (struct m), 0, NULL));
+ dump_CFI_cdesc_t (b);
+ if (b->version != CFI_VERSION)
+ abort ();
+ if (b->rank != 0)
+ abort ();
+ if (b->attribute != CFI_attribute_pointer)
+ abort ();
+ if (b->base_addr)
+ abort ();
+ if (b->elem_len != sizeof (struct m))
+ abort ();
+
+ /* Call back into Fortran, passing the unallocated descriptors. */
+ ftest (a, b, 0);
+
+ /* Allocate and initialize both variables, and try again. */
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (a, NULL, NULL, 0));
+ dump_CFI_cdesc_t (a);
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof (struct m))
+ abort ();
+ ((struct m *)a->base_addr)->i = imagic;
+ ((struct m *)a->base_addr)->j = jmagic;
+
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (b, NULL, NULL, 0));
+ dump_CFI_cdesc_t (b);
+ if (!b->base_addr)
+ abort ();
+ if (b->elem_len != sizeof (struct m))
+ abort ();
+ ((struct m *)b->base_addr)->i = imagic + 1;
+ ((struct m *)b->base_addr)->j = jmagic + 1;
+
+ ftest (a, b, 1);
+
+ /* Deallocate both objects and try again. */
+ check_CFI_status ("CFI_deallocate", CFI_deallocate (a));
+ if (a->base_addr)
+ abort ();
+ check_CFI_status ("CFI_deallocate", CFI_deallocate (b));
+ if (b->base_addr)
+ abort ();
+ ftest (a, b, 0);
+}
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-3.f90
@@ -0,0 +1,58 @@
+! { dg-do run }
+! { dg-additional-sources "cf-descriptor-3-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that building a descriptor for an allocatable
+! or pointer scalar argument in C works and that you can use it to call
+! back into a Fortran function declared to have c binding.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer(C_INT), parameter :: imagic = 42, jmagic = 69
+end module
+
+subroutine ftest (a, b, initp) bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a
+ type(m), pointer :: b
+ integer(C_INT), value :: initp
+
+ if (rank(a) .ne. 0) stop 101
+ if (rank(b) .ne. 0) stop 101
+
+ if (initp .ne. 0 .and. .not. allocated(a)) stop 102
+ if (initp .eq. 0 .and. allocated(a)) stop 103
+ if (initp .ne. 0 .and. .not. associated(b)) stop 104
+ if (initp .eq. 0 .and. associated(b)) stop 105
+
+ if (initp .ne. 0) then
+ if (a%i .ne. imagic) stop 201
+ if (a%j .ne. jmagic) stop 202
+ if (b%i .ne. imagic + 1) stop 203
+ if (b%j .ne. jmagic + 1) stop 204
+ end if
+end subroutine
+
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (i, j) bind (c)
+ use iso_c_binding
+ integer(C_INT), value :: i, j
+ end subroutine
+ end interface
+
+ ! ctest will call ftest with both an unallocated and allocated argument.
+
+ call ctest (imagic, jmagic)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-4-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-4-c.c
@@ -0,0 +1,112 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (int imagic, int jmagic);
+extern void ftest (CFI_cdesc_t *a, CFI_cdesc_t *b, int initp);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest (int imax, int jmax)
+{
+ CFI_CDESC_T(2) adesc;
+ CFI_CDESC_T(2) bdesc;
+ CFI_cdesc_t *a = (CFI_cdesc_t *) &adesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+ struct m* mp;
+ CFI_index_t lower[2], upper[2], subscripts[2];
+ CFI_index_t i, j;
+
+ /* Create the descriptor for a, then sanity-check it. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (a, NULL, CFI_attribute_allocatable,
+ CFI_type_struct,
+ sizeof (struct m), 2, NULL));
+ dump_CFI_cdesc_t (a);
+ if (a->version != CFI_VERSION)
+ abort ();
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof (struct m))
+ abort ();
+
+ /* Likewise for b. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, NULL, CFI_attribute_pointer,
+ CFI_type_struct,
+ sizeof (struct m), 2, NULL));
+ dump_CFI_cdesc_t (b);
+ if (b->version != CFI_VERSION)
+ abort ();
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_pointer)
+ abort ();
+ if (b->base_addr)
+ abort ();
+ if (b->elem_len != sizeof (struct m))
+ abort ();
+
+ /* Call back into Fortran, passing the unallocated descriptors. */
+ ftest (a, b, 0);
+
+ /* Allocate and initialize both variables, and try again. */
+ lower[0] = 1;
+ lower[1] = 1;
+ upper[0] = imax;
+ upper[1] = jmax;
+
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (a, lower, upper, 0));
+ dump_CFI_cdesc_t (a);
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof (struct m))
+ abort ();
+
+ upper[0] = jmax;
+ upper[1] = imax;
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (b, lower, upper, 0));
+ dump_CFI_cdesc_t (b);
+ if (!b->base_addr)
+ abort ();
+ if (b->elem_len != sizeof (struct m))
+ abort ();
+
+ for (i = 1; i <= imax; i++)
+ for (j = 1; j <= jmax; j++)
+ {
+ subscripts[0] = i;
+ subscripts[1] = j;
+ mp = (struct m *) CFI_address (a, subscripts);
+ mp->i = i;
+ mp->j = j;
+ subscripts[0] = j;
+ subscripts[1] = i;
+ mp = (struct m *) CFI_address (b, subscripts);
+ mp->i = i;
+ mp->j = j;
+ }
+
+ ftest (a, b, 1);
+
+ /* Deallocate both objects and try again. */
+ check_CFI_status ("CFI_deallocate", CFI_deallocate (a));
+ if (a->base_addr)
+ abort ();
+ check_CFI_status ("CFI_deallocate", CFI_deallocate (b));
+ if (b->base_addr)
+ abort ();
+ ftest (a, b, 0);
+}
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-4.f90
@@ -0,0 +1,73 @@
+! { dg-do run }
+! { dg-additional-sources "cf-descriptor-4-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that building a descriptor for an allocatable
+! or pointer array argument in C works and that you can use it to call
+! back into a Fortran function declared to have c binding.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer(C_INT), parameter :: imax=3, jmax=6
+end module
+
+subroutine ftest (a, b, initp) bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a(:,:)
+ type(m), pointer :: b(:,:)
+ integer(C_INT), value :: initp
+ integer :: i, j
+
+ if (rank(a) .ne. 2) stop 101
+ if (rank(b) .ne. 2) stop 101
+
+ if (initp .ne. 0 .and. .not. allocated(a)) stop 102
+ if (initp .eq. 0 .and. allocated(a)) stop 103
+ if (initp .ne. 0 .and. .not. associated(b)) stop 104
+ if (initp .eq. 0 .and. associated(b)) stop 105
+
+ if (initp .ne. 0) then
+ if (lbound (a, 1) .ne. 1) stop 201
+ if (lbound (a, 2) .ne. 1) stop 202
+ if (lbound (b, 2) .ne. 1) stop 203
+ if (lbound (b, 1) .ne. 1) stop 204
+ if (ubound (a, 1) .ne. imax) stop 205
+ if (ubound (a, 2) .ne. jmax) stop 206
+ if (ubound (b, 2) .ne. imax) stop 207
+ if (ubound (b, 1) .ne. jmax) stop 208
+
+ do i = 1, imax
+ do j = 1, jmax
+ if (a(i,j)%i .ne. i) stop 301
+ if (a(i,j)%j .ne. j) stop 302
+ if (b(j,i)%i .ne. i) stop 303
+ if (b(j,i)%j .ne. j) stop 303
+ end do
+ end do
+
+ end if
+end subroutine
+
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (i, j) bind (c)
+ use iso_c_binding
+ integer(C_INT), value :: i, j
+ end subroutine
+ end interface
+
+ ! ctest will call ftest with both an unallocated and allocated argument.
+
+ call ctest (imax, jmax)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-5-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-5-c.c
@@ -0,0 +1,42 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (int n);
+extern void ftest (CFI_cdesc_t *a, int n);
+
+#define BUFSIZE 512
+static char adata[BUFSIZE];
+
+void
+ctest (int n)
+{
+ CFI_CDESC_T(0) adesc;
+ CFI_cdesc_t *a = (CFI_cdesc_t *) &adesc;
+
+ /* Use a fixed-size static buffer instead of allocating one dynamically. */
+ if (n > BUFSIZE)
+ abort ();
+
+ /* Fill in adesc. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (a, adata, CFI_attribute_other,
+ CFI_type_char, n, 0, NULL));
+
+ /* Sanity checking to make sure the descriptor has been initialized
+ properly. */
+ dump_CFI_cdesc_t (a);
+ if (a->version != CFI_VERSION)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->elem_len != n)
+ abort ();
+
+ /* Call back into Fortran. */
+ ftest (a, n);
+}
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-5.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-5.f90
@@ -0,0 +1,31 @@
+! PR92482
+! { dg-do run }
+! { dg-additional-sources "cf-descriptor-5-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that building a descriptor for a character object
+! in C works and that you can use it to call back into a Fortran function
+! with an assumed-length dummy that is declared with C binding.
+
+subroutine ftest (a, n) bind (c, name="ftest")
+ use iso_c_binding
+ character(kind=C_CHAR, len=*) :: a
+ integer(C_INT), value :: n
+
+ if (len (a) .ne. n) stop 101
+end subroutine
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (n) bind (c)
+ use iso_c_binding
+ integer(C_INT), value :: n
+ end subroutine
+ end interface
+
+ call ctest (42)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-6-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-6-c.c
@@ -0,0 +1,81 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, int lb1, int lb2, int ub1, int ub2, int step1, int step2);
+extern void ftest (CFI_cdesc_t *b);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest (CFI_cdesc_t *a, int lb1, int lb2, int ub1, int ub2,
+ int step1, int step2)
+{
+ CFI_CDESC_T(2) bdesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+ CFI_index_t lb[2], ub[2], step[2];
+ int i, j;
+
+ fprintf (stderr, "got new bound info (%d:%d:%d, %d:%d:%d)\n",
+ lb1, ub1, step1, lb2, ub2, step2);
+ lb[0] = lb1 - 1;
+ lb[1] = lb2 - 1;
+ ub[0] = ub1 - 1;
+ ub[1] = ub2 - 1;
+ step[0] = step1;
+ step[1] = step2;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 2)
+ abort ();
+
+ /* Fill in bdesc. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, NULL, CFI_attribute_pointer,
+ CFI_type_struct,
+ sizeof (struct m), 2, NULL));
+ check_CFI_status ("CFI_section",
+ CFI_section (b, a, lb, ub, step));
+
+ /* Sanity checking to make sure the descriptor has been initialized
+ properly. */
+ dump_CFI_cdesc_t (b);
+ if (b->version != CFI_VERSION)
+ abort ();
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_pointer)
+ abort ();
+ if (!b->base_addr)
+ abort ();
+ if (CFI_is_contiguous (b))
+ abort ();
+
+ for (j = b->dim[1].lower_bound;
+ j < b->dim[1].lower_bound + b->dim[1].extent;
+ j++)
+ {
+ for (i = b->dim[0].lower_bound;
+ i < b->dim[0].lower_bound + b->dim[0].extent;
+ i++)
+ {
+ CFI_index_t subscripts[2];
+ struct m *mp;
+ subscripts[0] = i;
+ subscripts[1] = j;
+ mp = (struct m *) CFI_address (b, subscripts);
+ fprintf (stderr, "b(%d,%d) = (%d,%d)\n", i, j, mp->i, mp->j);
+ }
+ }
+
+ /* Call back into Fortran. */
+ ftest (b);
+}
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-6.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-6.f90
@@ -0,0 +1,72 @@
+! { dg-do run }
+! { dg-additional-sources "cf-descriptor-6-c.c dump-descriptors.c" }
+!
+! This program tests passing the result of the CFI_section C library
+! routine back to Fortran. Most of the work happens on the C side.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+ integer, parameter :: ilb=2, jlb=1
+ integer, parameter :: iub=8, jub=5
+ integer, parameter :: istep=3, jstep=2
+ integer, parameter :: isize=3, jsize=3
+end module
+
+subroutine ftest (b) bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ type(m), pointer :: b(:,:)
+ integer :: i, j, ii, jj
+
+ if (size (b, 1) .ne. isize) stop 103
+ if (size (b, 2) .ne. jsize) stop 104
+
+ ! ii and jj iterate over the elements of b
+ ! i and j iterate over the original array
+ jj = lbound (b, 2)
+ do j = jlb, jub, jstep
+ ii = lbound (b, 1)
+ do i = ilb, iub, istep
+ if (b (ii, jj)%i .ne. i) stop 203
+ if (b (ii, jj)%j .ne. j) stop 204
+ ii = ii + 1
+ end do
+ jj = jj + 1
+ end do
+end subroutine
+
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (a, lb1, lb2, ub1, ub2, step1, step2) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ integer(C_INT), value :: lb1, lb2, ub1, ub2, step1, step2
+ end subroutine
+ end interface
+
+ type(m), target :: aa(imax,jmax)
+ integer :: i, j
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ end do
+ end do
+
+ ! Pass the initialized array to a C function ctest, which will take
+ ! a section of it and pass it to ftest.
+
+ call ctest (aa, ilb, jlb, iub, jub, istep, jstep)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-7-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-7-c.c
@@ -0,0 +1,81 @@
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+extern void ftest (CFI_cdesc_t *iarray, CFI_cdesc_t *jarray);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest (CFI_cdesc_t *a)
+{
+ CFI_CDESC_T(2) idesc;
+ CFI_cdesc_t *iarray = (CFI_cdesc_t *) &idesc;
+ CFI_CDESC_T(2) jdesc;
+ CFI_cdesc_t *jarray = (CFI_cdesc_t *) &jdesc;
+ int i, j;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 2)
+ abort ();
+
+ /* Fill in the new descriptors. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (iarray, NULL, CFI_attribute_pointer,
+ CFI_type_int,
+ sizeof (int), 2, NULL));
+ check_CFI_status ("CFI_select_part",
+ CFI_select_part (iarray, a, offsetof (struct m, i),
+ sizeof (int)));
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (jarray, NULL, CFI_attribute_pointer,
+ CFI_type_int,
+ sizeof (int), 2, NULL));
+ check_CFI_status ("CFI_select_part",
+ CFI_select_part (jarray, a, offsetof (struct m, j),
+ sizeof (int)));
+
+ /* Sanity checking to make sure the descriptor has been initialized
+ properly. */
+ dump_CFI_cdesc_t (iarray);
+ if (iarray->version != CFI_VERSION)
+ abort ();
+ if (iarray->rank != 2)
+ abort ();
+ if (iarray->attribute != CFI_attribute_pointer)
+ abort ();
+ if (!iarray->base_addr)
+ abort ();
+ if (iarray->dim[0].extent != a->dim[0].extent)
+ abort ();
+ if (iarray->dim[1].extent != a->dim[1].extent)
+ abort ();
+
+ dump_CFI_cdesc_t (jarray);
+ if (jarray->version != CFI_VERSION)
+ abort ();
+ if (jarray->rank != 2)
+ abort ();
+ if (jarray->attribute != CFI_attribute_pointer)
+ abort ();
+ if (!jarray->base_addr)
+ abort ();
+ if (jarray->dim[0].extent != a->dim[0].extent)
+ abort ();
+ if (jarray->dim[1].extent != a->dim[1].extent)
+ abort ();
+
+ /* Call back into Fortran. */
+ ftest (iarray, jarray);
+}
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-7.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-7.f90
@@ -0,0 +1,74 @@
+! { dg-do run }
+! { dg-additional-sources "cf-descriptor-7-c.c dump-descriptors.c" }
+!
+! This program tests passing the result of the CFI_select_part C library
+! routine back to Fortran. Most of the work happens on the C side.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+subroutine ftest (iarray, jarray) bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ integer(C_INT), pointer :: iarray(:,:), jarray(:,:)
+
+ integer :: i, j, i1, i2, j1, j2
+
+ ! iarray and jarray must have the same shape as the original array,
+ ! but might be zero-indexed instead of one-indexed.
+ if (size (iarray, 1) .ne. imax) stop 101
+ if (size (iarray, 2) .ne. jmax) stop 102
+ if (size (jarray, 1) .ne. imax) stop 103
+ if (size (jarray, 2) .ne. jmax) stop 104
+
+ j1 = lbound(iarray, 2)
+ j2 = lbound(jarray, 2)
+ do j = 1, jmax
+ i1 = lbound(iarray, 1)
+ i2 = lbound(jarray, 1)
+ do i = 1, imax
+ if (iarray (i1, j1) .ne. i) stop 201
+ if (jarray (i2, j2) .ne. j) stop 202
+ i1 = i1 + 1
+ i2 = i2 + 1
+ end do
+ j1 = j1 + 1
+ j2 = j2 + 1
+ end do
+end subroutine
+
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ end subroutine
+ end interface
+
+ type(m), target :: aa(imax,jmax)
+ integer :: i, j
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ end do
+ end do
+
+ ! Pass the initialized array to a C function ctest, which will split it
+ ! into i and j component arrays and pass them to ftest.
+
+ call ctest (aa)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-8-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-8-c.c
@@ -0,0 +1,73 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+extern void ftest1 (CFI_cdesc_t *a, int lb1, int lb2);
+extern void ftest2 (CFI_cdesc_t *a);
+
+struct m {
+ int i;
+ int j;
+};
+
+#define imax 10
+#define jmax 5
+
+void
+ctest (CFI_cdesc_t *a)
+{
+
+ CFI_CDESC_T(2) bdesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+ int i, j;
+ CFI_index_t subscripts[2];
+ struct m* mp;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+
+ /* Fill in bdesc. */
+ subscripts[0] = a->dim[0].extent;
+ subscripts[1] = a->dim[1].extent;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, NULL, CFI_attribute_pointer,
+ CFI_type_struct,
+ sizeof (struct m), 2, subscripts));
+
+ /* Pass the unassociated pointer descriptor b back to Fortran for
+ checking. */
+ dump_CFI_cdesc_t (b);
+ ftest2 (b);
+
+ /* Point the descriptor b at the input argument array, and check that
+ on the Fortran side. */
+ subscripts[0] = a->dim[0].lower_bound;
+ subscripts[1] = a->dim[1].lower_bound;
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (b, a, subscripts));
+ dump_CFI_cdesc_t (b);
+ ftest1 (b, (int)subscripts[0], (int)subscripts[1]);
+
+ /* Diddle the lower bounds and try again. */
+ subscripts[0] = 42;
+ subscripts[1] = -69;
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (b, b, subscripts));
+ dump_CFI_cdesc_t (b);
+ ftest1 (b, 42, -69);
+
+ /* Disassociate the pointer and check that. */
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (b, NULL, NULL));
+ dump_CFI_cdesc_t (b);
+ ftest2 (b);
+}
Index: Fortran/gfortran/regression/c-interop/cf-descriptor-8.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-descriptor-8.f90
@@ -0,0 +1,78 @@
+! { dg-do run }
+! { dg-additional-sources "cf-descriptor-8-c.c dump-descriptors.c" }
+!
+! This program tests passing the result of the CFI_setpointer C library
+! function back to Fortran. Most of the work happens on the C side.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+subroutine ftest1 (a, lb1, lb2) bind (c, name="ftest1")
+ use iso_c_binding
+ use mm
+ type(m), pointer :: a(:,:)
+ integer(C_INT), value :: lb1, lb2
+ integer :: i, j, ii, jj
+
+ if (size (a,1) .ne. imax) stop 101
+ if (size (a,2) .ne. jmax) stop 102
+ if (lbound (a, 1) .ne. lb1) stop 103
+ if (lbound (a, 2) .ne. lb2) stop 104
+
+ if (.not. associated (a)) stop 105
+
+ jj = lb2
+ do j = 1, jmax
+ ii = lb1
+ do i = 1, imax
+ if (a(ii,jj)%i .ne. i) stop 201
+ if (a(ii,jj)%j .ne. j) stop 202
+ ii = ii + 1
+ end do
+ jj = jj + 1
+ end do
+end subroutine
+
+subroutine ftest2 (a) bind (c, name="ftest2")
+ use iso_c_binding
+ use mm
+ type(m), pointer :: a(:,:)
+
+ if (associated (a)) stop 301
+end subroutine
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ end subroutine
+ end interface
+
+ type(m), target :: aa(imax,jmax)
+ integer :: i, j
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ end do
+ end do
+
+ ! Pass the initialized array to a C function ctest, which will use it
+ ! as the target of a pointer array with various bounds, calling
+ ! ftest1 and ftest2 to check that CFI_setpointer did the right thing.
+
+ call ctest (aa)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-1-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-1-c.c
@@ -0,0 +1,87 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, CFI_cdesc_t *b);
+extern void ftest2 (CFI_cdesc_t *a, CFI_cdesc_t *b);
+
+struct m {
+ int i;
+ int j;
+};
+
+#define imax 10
+#define jmax 5
+
+void
+ctest (CFI_cdesc_t *a, CFI_cdesc_t *b)
+{
+ CFI_index_t i, j;
+ CFI_index_t s[2];
+ struct m *mpa, *mpb;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != imax)
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != jmax)
+ abort ();
+
+ dump_CFI_cdesc_t (b);
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_other)
+ abort ();
+ if (b->dim[0].lower_bound != 0)
+ abort ();
+ if (b->dim[0].extent != jmax)
+ abort ();
+ if (b->dim[1].lower_bound != 0)
+ abort ();
+ if (b->dim[1].extent != imax)
+ abort ();
+
+ /* Call back into Fortran, passing both the a and b arrays. */
+ ftest2 (a, b);
+
+ /* Check that we got a valid b array back. */
+ dump_CFI_cdesc_t (b);
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_other)
+ abort ();
+ if (b->dim[0].lower_bound != 0)
+ abort ();
+ if (b->dim[0].extent != jmax)
+ abort ();
+ if (b->dim[1].lower_bound != 0)
+ abort ();
+ if (b->dim[1].extent != imax)
+ abort ();
+
+ for (j = 0; j < jmax; j++)
+ for (i = 0; i < imax; i++)
+ {
+ s[0] = i;
+ s[1] = j;
+ mpa = (struct m *) CFI_address (a, s);
+ s[0] = j;
+ s[1] = i;
+ mpb = (struct m *) CFI_address (b, s);
+ if (mpa->i != mpb->i)
+ abort ();
+ if (mpa->j != mpb->j)
+ abort ();
+ }
+}
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-1.f90
@@ -0,0 +1,174 @@
+! { dg-do run }
+! { dg-additional-sources "cf-out-descriptor-1-c.c dump-descriptors.c" }
+!
+! This program checks that calling a Fortran function with C binding and
+! an intent(out) argument works from both C and Fortran. For this
+! test case the argument is an assumed-shape array.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+! frob has regular Fortran binding. It transposes input array argument
+! a into the intent(out) argument b.
+
+subroutine frob (a, b)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m), intent(out) :: b(:,:)
+ integer :: i, j
+
+ if (lbound (a, 1) .ne. lbound (b, 2)) stop 101
+ if (lbound (a, 2) .ne. lbound (b, 1)) stop 102
+ if (ubound (a, 1) .ne. ubound (b, 2)) stop 103
+ if (ubound (a, 2) .ne. ubound (b, 1)) stop 104
+
+ do j = lbound (a, 2), ubound (a, 2)
+ do i = lbound (a, 1), ubound (a, 1)
+ b(j,i) = a(i,j)
+ end do
+ end do
+end subroutine
+
+! check also has regular Fortran binding, and two input arguments.
+
+subroutine check (a, b)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:), b(:,:)
+ integer :: i, j
+
+ if (lbound (a, 1) .ne. 1 .or. lbound (b, 2) .ne. 1) stop 101
+ if (lbound (a, 2) .ne. 1 .or. lbound (b, 1) .ne. 1) stop 102
+ if (ubound (a, 1) .ne. ubound (b, 2)) stop 103
+ if (ubound (a, 2) .ne. ubound (b, 1)) stop 104
+
+ do j = 1, ubound (a, 2)
+ do i = 1, ubound (a, 1)
+ if (b(j,i)%i .ne. a(i,j)%i) stop 105
+ if (b(j,i)%j .ne. a(i,j)%j) stop 106
+ end do
+ end do
+end subroutine
+
+! ftest1 has C binding and calls frob. This allows us to test intent(out)
+! arguments passed back from Fortran binding to a Fortran function with C
+! binding.
+
+subroutine ftest1 (a, b) bind (c, name="ftest1")
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m), intent(out) :: b(:,:)
+
+ interface
+ subroutine frob (a, b)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m), intent(out) :: b(:,:)
+ end subroutine
+ subroutine check (a, b)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:), b(:,:)
+ end subroutine
+ end interface
+
+ call frob (a, b)
+ call check (a, b)
+end subroutine
+
+! ftest2 has C binding and calls ftest1. This allows us to test intent(out)
+! arguments passed between two Fortran functions with C binding.
+
+subroutine ftest2 (a, b) bind (c, name="ftest2")
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m), intent(out) :: b(:,:)
+
+ interface
+ subroutine ftest1 (a, b) bind (c, name="ftest1")
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m), intent(out) :: b(:,:)
+ end subroutine
+ subroutine check (a, b)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:), b(:,:)
+ end subroutine
+ end interface
+
+ call ftest1 (a, b)
+ call check (a, b)
+end subroutine
+
+! main calls ftest2 directly and also indirectly from a C function ctest.
+! The former allows us to test intent(out) arguments passed back from a
+! Fortran routine with C binding to a regular Fortran routine, and the
+! latter tests passing them back from Fortran to C and C to Fortran.
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ftest2 (a, b) bind (c, name="ftest2")
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m), intent(out) :: b(:,:)
+ end subroutine
+ subroutine ctest (a, b) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m), intent(out) :: b(:,:)
+ end subroutine
+ subroutine check (a, b)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:), b(:,:)
+ end subroutine
+ end interface
+
+ type(m) :: aa(imax,jmax), bb(jmax,imax)
+ integer :: i, j
+
+ ! initialize
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ bb(j,i)%i = -1
+ bb(j,i)%j = -2
+ end do
+ end do
+
+ call ftest2 (aa, bb)
+ call check (aa, bb)
+
+ ! initialize again
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ bb(j,i)%i = -1
+ bb(j,i)%j = -2
+ end do
+ end do
+
+ call ctest (aa, bb)
+ call check (aa, bb)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-2-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-2-c.c
@@ -0,0 +1,87 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, CFI_cdesc_t *b);
+extern void ftest2 (CFI_cdesc_t *a, CFI_cdesc_t *b);
+
+struct m {
+ int i;
+ int j;
+};
+
+#define imax 10
+#define jmax 5
+
+void
+ctest (CFI_cdesc_t *a, CFI_cdesc_t *b)
+{
+ CFI_index_t i, j;
+ CFI_index_t s[2];
+ struct m *mpa, *mpb;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != imax)
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != jmax)
+ abort ();
+
+ dump_CFI_cdesc_t (b);
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_other)
+ abort ();
+ if (b->dim[0].lower_bound != 0)
+ abort ();
+ if (b->dim[0].extent != jmax)
+ abort ();
+ if (b->dim[1].lower_bound != 0)
+ abort ();
+ if (b->dim[1].extent != imax)
+ abort ();
+
+ /* Call back into Fortran, passing both the a and b arrays. */
+ ftest2 (a, b);
+
+ /* Check that we got a valid b array back. */
+ dump_CFI_cdesc_t (b);
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_other)
+ abort ();
+ if (b->dim[0].lower_bound != 0)
+ abort ();
+ if (b->dim[0].extent != jmax)
+ abort ();
+ if (b->dim[1].lower_bound != 0)
+ abort ();
+ if (b->dim[1].extent != imax)
+ abort ();
+
+ for (j = 0; j < jmax; j++)
+ for (i = 0; i < imax; i++)
+ {
+ s[0] = i;
+ s[1] = j;
+ mpa = (struct m *) CFI_address (a, s);
+ s[0] = j;
+ s[1] = i;
+ mpb = (struct m *) CFI_address (b, s);
+ if (mpa->i != mpb->i)
+ abort ();
+ if (mpa->j != mpb->j)
+ abort ();
+ }
+}
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-2.f90
@@ -0,0 +1,157 @@
+! { dg-do run }
+! { dg-additional-sources "cf-out-descriptor-2-c.c dump-descriptors.c" }
+!
+! This program checks that calling a Fortran function with C binding and
+! an intent(out) argument works from both C and Fortran. For this
+! test case the argument is an assumed-rank array.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+! The call chains we'll be testing will be
+! main -> ctest -> ftest1
+! main -> ftest2 -> ftest1
+! main -> ftest1
+! where everything has "c" binding except main.
+
+! ftest1 has C binding and transposes a into b.
+
+subroutine ftest1 (a, b) bind (c, name="ftest1")
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ type(m), intent(out) :: b(..)
+
+ select rank (a)
+ rank (2)
+ select rank (b)
+ rank (2)
+ b = transpose (a)
+ rank default
+ stop 101
+ end select
+ rank default
+ stop 102
+ end select
+end subroutine
+
+! ftest2 has C binding and calls ftest1.
+
+subroutine ftest2 (a, b) bind (c, name="ftest2")
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ type(m), intent(out) :: b(..)
+
+ interface
+ subroutine ftest1 (a, b) bind (c, name="ftest1")
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ type(m), intent(out) :: b(..)
+ end subroutine
+ end interface
+
+ call ftest1 (a, b)
+ if (rank (a) .ne. 2) stop 201
+ if (rank (b) .ne. 2) stop 202
+end subroutine
+
+! main calls ftest2 directly and also indirectly from a C function ctest.
+! The former allows us to test intent(out) arguments passed back from a
+! Fortran routine with C binding to a regular Fortran routine, and the
+! latter tests passing them back from Fortran to C and C to Fortran.
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ftest1 (a, b) bind (c, name="ftest2")
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ type(m), intent(out) :: b(..)
+ end subroutine
+ subroutine ftest2 (a, b) bind (c, name="ftest2")
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ type(m), intent(out) :: b(..)
+ end subroutine
+ subroutine ctest (a, b) bind (c, name="ctest")
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ type(m), intent(out) :: b(..)
+ end subroutine
+ end interface
+
+ type(m) :: aa(imax,jmax), bb(jmax,imax)
+ integer :: i, j
+
+ ! initialize
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ bb(j,i)%i = -1
+ bb(j,i)%j = -2
+ end do
+ end do
+
+ ! frob and check
+ call ftest1 (aa, bb)
+ do j = 1, jmax
+ do i = 1, imax
+ if (aa(i,j)%i .ne. bb(j,i)%i) stop 301
+ if (aa(i,j)%j .ne. bb(j,i)%j) stop 302
+ end do
+ end do
+
+ ! initialize again
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ bb(j,i)%i = -1
+ bb(j,i)%j = -2
+ end do
+ end do
+
+ ! frob and check
+ call ftest2 (aa, bb)
+ do j = 1, jmax
+ do i = 1, imax
+ if (aa(i,j)%i .ne. bb(j,i)%i) stop 401
+ if (aa(i,j)%j .ne. bb(j,i)%j) stop 402
+ end do
+ end do
+
+ ! initialize again
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ bb(j,i)%i = -1
+ bb(j,i)%j = -2
+ end do
+ end do
+
+ ! frob and check
+ call ctest (aa, bb)
+ do j = 1, jmax
+ do i = 1, imax
+ if (aa(i,j)%i .ne. bb(j,i)%i) stop 501
+ if (aa(i,j)%j .ne. bb(j,i)%j) stop 502
+ end do
+ end do
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-3-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-3-c.c
@@ -0,0 +1,108 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (int imagic, int jmagic);
+extern void frob (CFI_cdesc_t *a, CFI_cdesc_t *aa, CFI_cdesc_t *p);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest (int imagic, int jmagic)
+{
+ CFI_CDESC_T(0) adesc;
+ CFI_CDESC_T(0) aadesc;
+ CFI_CDESC_T(0) bdesc;
+ CFI_cdesc_t *a = (CFI_cdesc_t *) &adesc;
+ CFI_cdesc_t *aa = (CFI_cdesc_t *) &aadesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+
+ /* Create and sanity-check descriptors. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (a, NULL, CFI_attribute_allocatable,
+ CFI_type_struct,
+ sizeof (struct m), 0, NULL));
+ dump_CFI_cdesc_t (a);
+ if (a->version != CFI_VERSION)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof (struct m))
+ abort ();
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (aa, NULL, CFI_attribute_allocatable,
+ CFI_type_struct,
+ sizeof (struct m), 0, NULL));
+ dump_CFI_cdesc_t (aa);
+ if (aa->version != CFI_VERSION)
+ abort ();
+ if (aa->rank != 0)
+ abort ();
+ if (aa->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (aa->base_addr)
+ abort ();
+ if (aa->elem_len != sizeof (struct m))
+ abort ();
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (aa, NULL, NULL, 0));
+ ((struct m *)aa->base_addr)->i = 0;
+ ((struct m *)aa->base_addr)->j = 0;
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, NULL, CFI_attribute_pointer,
+ CFI_type_struct,
+ sizeof (struct m), 0, NULL));
+ dump_CFI_cdesc_t (b);
+ if (b->version != CFI_VERSION)
+ abort ();
+ if (b->rank != 0)
+ abort ();
+ if (b->attribute != CFI_attribute_pointer)
+ abort ();
+ if (b->base_addr)
+ abort ();
+ if (b->elem_len != sizeof (struct m))
+ abort ();
+
+ /* Call back into Fortran, which will allocate and initialize the
+ objects. */
+ frob (a, aa, b);
+
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof (struct m))
+ abort ();
+ if (((struct m *)a->base_addr)->i != imagic)
+ abort ();
+ if (((struct m *)a->base_addr)->j != jmagic)
+ abort ();
+
+ if (!aa->base_addr)
+ abort ();
+ if (aa->elem_len != sizeof (struct m))
+ abort ();
+ if (((struct m *)aa->base_addr)->i != imagic)
+ abort ();
+ if (((struct m *)aa->base_addr)->j != jmagic)
+ abort ();
+
+ if (!b->base_addr)
+ abort ();
+ if (b->elem_len != sizeof (struct m))
+ abort ();
+ if (((struct m *)b->base_addr)->i != imagic)
+ abort ();
+ if (((struct m *)b->base_addr)->j != jmagic)
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-3.f90
@@ -0,0 +1,134 @@
+! PR 92621 (?)
+! { dg-do run }
+! { dg-additional-sources "cf-out-descriptor-3-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that calling a Fortran function with C binding and
+! an intent(out) argument works from both C and Fortran. For this
+! test case the argument is an allocatable or pointer scalar.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imagic=-1, jmagic=42
+
+end module
+
+! The call chains being tested here are
+! main -> frob
+! main -> ftest -> frob
+! main -> ctest -> frob
+! where everything other than main has C binding.
+
+! frob allocates and initializes its arguments.
+! There are two allocatable dummies so that we can pass both
+! unallocated (a) and allocated (aa).
+
+subroutine frob (a, aa, p) bind (c, name="frob")
+ use iso_c_binding
+ use mm
+ type(m), intent(out), allocatable :: a, aa
+ type(m), intent(out), pointer :: p
+
+ if (allocated (a)) stop 101
+ allocate (a)
+ a%i = imagic
+ a%j = jmagic
+
+ if (allocated (aa)) stop 102
+ allocate (aa)
+ aa%i = imagic
+ aa%j = jmagic
+
+ ! association status of p is undefined on entry
+ allocate (p)
+ p%i = imagic
+ p%j = jmagic
+end subroutine
+
+subroutine ftest () bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a, aa
+ type(m), pointer :: p
+
+ interface
+ subroutine frob (a, aa, p) bind (c, name="frob")
+ use iso_c_binding
+ use mm
+ type(m), intent(out), allocatable :: a, aa
+ type(m), intent(out), pointer :: p
+ end subroutine
+ end interface
+
+ p => NULL ()
+ allocate (aa)
+ aa%i = 0
+ aa%j = 0
+ call frob (a, aa, p)
+
+ if (.not. allocated (a)) stop 201
+ if (a%i .ne. imagic) stop 202
+ if (a%j .ne. jmagic) stop 203
+
+ if (.not. allocated (aa)) stop 204
+ if (a%i .ne. imagic) stop 205
+ if (a%j .ne. jmagic) stop 206
+
+ if (.not. associated (p)) stop 207
+ if (p%i .ne. imagic) stop 208
+ if (p%j .ne. jmagic) stop 209
+
+end subroutine
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine frob (a, aa, p) bind (c, name="frob")
+ use iso_c_binding
+ use mm
+ type(m), intent(out), allocatable :: a, aa
+ type(m), intent(out), pointer :: p
+ end subroutine
+ subroutine ftest () bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ end subroutine
+ subroutine ctest (ii, jj) bind (c, name="ctest")
+ use iso_c_binding
+ use mm
+ integer(C_INT), value :: ii, jj
+ end subroutine
+ end interface
+
+ type(m), allocatable :: a, aa
+ type(m), pointer :: p
+
+ p => NULL ()
+ allocate (aa)
+ aa%i = 0
+ aa%j = 0
+ call frob (a, aa, p)
+
+ if (.not. allocated (a)) stop 201
+ if (a%i .ne. imagic) stop 202
+ if (a%j .ne. jmagic) stop 203
+
+ if (.not. allocated (aa)) stop 204
+ if (a%i .ne. imagic) stop 205
+ if (a%j .ne. jmagic) stop 206
+
+ if (.not. associated (p)) stop 207
+ if (p%i .ne. imagic) stop 208
+ if (p%j .ne. jmagic) stop 209
+
+ call ftest
+ call ctest (imagic, jmagic)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-4-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-4-c.c
@@ -0,0 +1,175 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (int imax, int jmax);
+extern void frob (CFI_cdesc_t *a, CFI_cdesc_t *aa, CFI_cdesc_t *p);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest (int imax, int jmax)
+{
+ CFI_CDESC_T(2) adesc;
+ CFI_CDESC_T(2) aadesc;
+ CFI_CDESC_T(2) bdesc;
+ CFI_cdesc_t *a = (CFI_cdesc_t *) &adesc;
+ CFI_cdesc_t *aa = (CFI_cdesc_t *) &aadesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+ CFI_index_t i, j;
+ CFI_index_t s[2];
+ CFI_index_t lb[2], ub[2];
+ struct m* mp;
+
+ /* Create and sanity-check a. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (a, NULL, CFI_attribute_allocatable,
+ CFI_type_struct,
+ sizeof (struct m), 2, NULL));
+ dump_CFI_cdesc_t (a);
+ if (a->version != CFI_VERSION)
+ abort ();
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof (struct m))
+ abort ();
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (aa, NULL, CFI_attribute_allocatable,
+ CFI_type_struct,
+ sizeof (struct m), 2, NULL));
+ dump_CFI_cdesc_t (aa);
+ if (aa->version != CFI_VERSION)
+ abort ();
+ if (aa->rank != 2)
+ abort ();
+ if (aa->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (aa->base_addr)
+ abort ();
+ if (aa->elem_len != sizeof (struct m))
+ abort ();
+
+ /* aa is allocated/initialized so that we can confirm that it's
+ magically deallocated when passed as intent(out). */
+ lb[0] = 0;
+ lb[1] = 0;
+ ub[0] = jmax;
+ ub[1] = jmax;
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (aa, lb, ub, 0));
+ for (j = 1; j <= jmax; j++)
+ for (i = 1; i <= imax; i++)
+ {
+ s[0] = j;
+ s[1] = i;
+ mp = (struct m *)CFI_address (aa, s);
+ mp->i = 0;
+ mp->j = 0;
+ }
+
+ /* Likewise create and sanity-check b. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, NULL, CFI_attribute_pointer,
+ CFI_type_struct,
+ sizeof (struct m), 2, NULL));
+ dump_CFI_cdesc_t (b);
+ if (b->version != CFI_VERSION)
+ abort ();
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_pointer)
+ abort ();
+ if (b->base_addr)
+ abort ();
+ if (b->elem_len != sizeof (struct m))
+ abort ();
+
+ /* Call back into Fortran, which will allocate and initialize the
+ objects. */
+ frob (a, aa, b);
+
+ dump_CFI_cdesc_t (a);
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof (struct m))
+ abort ();
+ if (a->dim[0].lower_bound != 1)
+ abort ();
+ if (a->dim[0].extent != imax)
+ abort ();
+ if (a->dim[1].lower_bound != 1)
+ abort ();
+ if (a->dim[1].extent != jmax)
+ abort ();
+ for (j = 1; j <= jmax; j++)
+ for (i = 1; i <= imax; i++)
+ {
+ s[0] = i;
+ s[1] = j;
+ mp = (struct m *)CFI_address (a, s);
+ if (mp->i != i)
+ abort ();
+ if (mp->j != j)
+ abort ();
+ }
+
+ dump_CFI_cdesc_t (aa);
+ if (!aa->base_addr)
+ abort ();
+ if (aa->elem_len != sizeof (struct m))
+ abort ();
+ if (aa->dim[0].lower_bound != 1)
+ abort ();
+ if (aa->dim[0].extent != imax)
+ abort ();
+ if (aa->dim[1].lower_bound != 1)
+ abort ();
+ if (aa->dim[1].extent != jmax)
+ abort ();
+ for (j = 1; j <= jmax; j++)
+ for (i = 1; i <= imax; i++)
+ {
+ s[0] = i;
+ s[1] = j;
+ mp = (struct m *)CFI_address (aa, s);
+ if (mp->i != i)
+ abort ();
+ if (mp->j != j)
+ abort ();
+ }
+
+ dump_CFI_cdesc_t (b);
+ if (!b->base_addr)
+ abort ();
+ if (b->elem_len != sizeof (struct m))
+ abort ();
+ if (b->dim[0].lower_bound != 1)
+ abort ();
+ if (b->dim[0].extent != jmax)
+ abort ();
+ if (b->dim[1].lower_bound != 1)
+ abort ();
+ if (b->dim[1].extent != imax)
+ abort ();
+ for (j = 1; j <= jmax; j++)
+ for (i = 1; i <= imax; i++)
+ {
+ s[0] = j;
+ s[1] = i;
+ mp = (struct m *)CFI_address (b, s);
+ if (mp->i != i)
+ abort ();
+ if (mp->j != j)
+ abort ();
+ }
+}
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-4.f90
@@ -0,0 +1,207 @@
+! PR 92621 (?)
+! { dg-do run }
+! { dg-additional-sources "cf-out-descriptor-4-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that calling a Fortran function with C binding and
+! an intent(out) argument works from both C and Fortran. For this
+! test case the argument is an allocatable or pointer array.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=5, jmax=10
+
+end module
+
+! The call chains being tested here are
+! main -> frob
+! main -> ftest -> frob
+! main -> ctest -> frob
+! where everything other than main has C binding.
+
+! frob allocates and initializes its arguments.
+! There are two allocatable dummies so that we can pass both
+! unallocated (a) and allocated (aa).
+
+subroutine frob (a, aa, p) bind (c, name="frob")
+ use iso_c_binding
+ use mm
+ type(m), intent(out), allocatable :: a(:,:), aa(:,:)
+ type(m), intent(out), pointer :: p(:,:)
+ integer :: i, j
+
+ if (allocated (a)) stop 101
+ allocate (a (imax, jmax))
+ do j = 1, jmax
+ do i = 1, imax
+ a(i,j)%i = i
+ a(i,j)%j = j
+ end do
+ end do
+
+ if (allocated (aa)) stop 102
+ allocate (aa (imax, jmax))
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ end do
+ end do
+
+ allocate (p (jmax, imax))
+ do j = 1, jmax
+ do i = 1, imax
+ p(j,i)%i = i
+ p(j,i)%j = j
+ end do
+ end do
+end subroutine
+
+subroutine ftest () bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a(:,:), aa(:,:)
+ type(m), pointer :: p(:,:)
+
+ integer :: i, j
+
+ interface
+ subroutine frob (a, aa, p) bind (c, name="frob")
+ use iso_c_binding
+ use mm
+ type(m), intent(out), allocatable :: a(:,:), aa(:,:)
+ type(m), intent(out), pointer :: p(:,:)
+ end subroutine
+ end interface
+
+ p => NULL ()
+ if (allocated (a) .or. allocated (aa)) stop 200
+ allocate (aa (jmax, imax))
+ do j = 1, jmax
+ do i = 1, imax
+ aa(j,i)%i = 0
+ aa(j,i)%j = 0
+ end do
+ end do
+ call frob (a, aa, p)
+
+ if (.not. allocated (a)) stop 201
+ if (lbound (a, 1) .ne. 1) stop 202
+ if (lbound (a, 2) .ne. 1) stop 203
+ if (ubound (a, 1) .ne. imax) stop 204
+ if (ubound (a, 2) .ne. jmax) stop 205
+ do j = 1, jmax
+ do i = 1, imax
+ if (a(i,j)%i .ne. i) stop 206
+ if (a(i,j)%j .ne. j) stop 207
+ end do
+ end do
+
+ if (.not. allocated (aa)) stop 211
+ if (lbound (aa, 1) .ne. 1) stop 212
+ if (lbound (aa, 2) .ne. 1) stop 213
+ if (ubound (aa, 1) .ne. imax) stop 214
+ if (ubound (aa, 2) .ne. jmax) stop 215
+ do j = 1, jmax
+ do i = 1, imax
+ if (aa(i,j)%i .ne. i) stop 216
+ if (aa(i,j)%j .ne. j) stop 217
+ end do
+ end do
+
+ if (.not. associated (p)) stop 221
+ if (lbound (p, 1) .ne. 1) stop 222
+ if (lbound (p, 2) .ne. 1) stop 223
+ if (ubound (p, 1) .ne. jmax) stop 224
+ if (ubound (p, 2) .ne. imax) stop 225
+ do j = 1, jmax
+ do i = 1, imax
+ if (p(j,i)%i .ne. i) stop 226
+ if (p(j,i)%j .ne. j) stop 227
+ end do
+ end do
+
+end subroutine
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine frob (a, aa, p) bind (c, name="frob")
+ use iso_c_binding
+ use mm
+ type(m), intent(out), allocatable :: a(:,:), aa(:,:)
+ type(m), intent(out), pointer :: p(:,:)
+ end subroutine
+ subroutine ftest () bind (c, name="ftest")
+ use iso_c_binding
+ use mm
+ end subroutine
+ subroutine ctest (ii, jj) bind (c, name="ctest")
+ use iso_c_binding
+ use mm
+ integer(C_INT), value :: ii, jj
+ end subroutine
+ end interface
+
+ type(m), allocatable :: a(:,:), aa(:,:)
+ type(m), pointer :: p(:,:)
+ integer :: i, j
+
+ p => NULL ()
+ if (allocated (a) .or. allocated (aa)) stop 300
+ allocate (aa (jmax, imax))
+ do j = 1, jmax
+ do i = 1, imax
+ aa(j,i)%i = 0
+ aa(j,i)%j = 0
+ end do
+ end do
+ call frob (a, aa, p)
+
+ if (.not. allocated (a)) stop 301
+ if (lbound (a, 1) .ne. 1) stop 302
+ if (lbound (a, 2) .ne. 1) stop 303
+ if (ubound (a, 1) .ne. imax) stop 304
+ if (ubound (a, 2) .ne. jmax) stop 305
+ do j = 1, jmax
+ do i = 1, imax
+ if (a(i,j)%i .ne. i) stop 306
+ if (a(i,j)%j .ne. j) stop 307
+ end do
+ end do
+
+ if (.not. allocated (aa)) stop 311
+ if (lbound (aa, 1) .ne. 1) stop 312
+ if (lbound (aa, 2) .ne. 1) stop 313
+ if (ubound (aa, 1) .ne. imax) stop 314
+ if (ubound (aa, 2) .ne. jmax) stop 315
+ do j = 1, jmax
+ do i = 1, imax
+ if (aa(i,j)%i .ne. i) stop 316
+ if (aa(i,j)%j .ne. j) stop 317
+ end do
+ end do
+
+ if (.not. associated (p)) stop 321
+ if (lbound (p, 1) .ne. 1) stop 322
+ if (lbound (p, 2) .ne. 1) stop 323
+ if (ubound (p, 1) .ne. jmax) stop 324
+ if (ubound (p, 2) .ne. imax) stop 325
+ do j = 1, jmax
+ do i = 1, imax
+ if (p(j,i)%i .ne. i) stop 326
+ if (p(j,i)%j .ne. j) stop 327
+ end do
+ end do
+
+ call ftest
+ call ctest (imax, jmax)
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-5-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-5-c.c
@@ -0,0 +1,31 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, int n);
+extern void ftest (CFI_cdesc_t *a, int n);
+
+void
+ctest (CFI_cdesc_t *a, int n)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* The actual argument object on the Fortran side has length n and
+ was passed as character(len=*).
+ Make sure that matches what's in the descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != n)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (a->type != CFI_type_char)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ ftest (a, n);
+}
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-5.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-5.f90
@@ -0,0 +1,48 @@
+! PR92482
+! { dg-do run }
+! { dg-additional-sources "cf-out-descriptor-5-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks use of an assumed-length character dummy argument
+! as an intent(out) parameter in subroutines with C binding.
+
+subroutine ftest (a, n) bind (c, name="ftest")
+ use iso_c_binding
+ character(kind=C_CHAR, len=*), intent(out) :: a
+ integer(C_INT), value :: n
+
+ if (len (a) .ne. n) stop 101
+ a = 'abcdefghijklmnopqrstuvwxyz'
+end subroutine
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a, n) bind (c)
+ use iso_c_binding
+ character(kind=C_CHAR, len=*), intent(out) :: a
+ integer(C_INT), value :: n
+ end subroutine
+
+ subroutine ftest (a, n) bind (c)
+ use iso_c_binding
+ character(kind=C_CHAR, len=*), intent(out) :: a
+ integer(C_INT), value :: n
+ end subroutine
+ end interface
+
+ character(kind=C_CHAR, len=42) :: aa
+
+ ! call ftest directly
+ aa = '12345678910'
+ call ftest (aa, 42)
+ print *, aa
+
+ ! ctest calls ftest indirectly
+ aa = '12345678910'
+ call ctest (aa, 42)
+ print *, aa
+
+end program
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-6-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-6-c.c
@@ -0,0 +1,42 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, int n);
+extern void ftest (CFI_cdesc_t *a, int n);
+
+void
+ctest (CFI_cdesc_t *a, int n)
+{
+ int i;
+ CFI_index_t s[1];
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != -1)
+ abort ();
+
+ ftest (a, n);
+
+ for (i = 0; i < n; i++)
+ {
+ s[0] = i;
+ if (*((int *)CFI_address (a, s)) != i + 1)
+ abort ();
+ }
+}
Index: Fortran/gfortran/regression/c-interop/cf-out-descriptor-6.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/cf-out-descriptor-6.f90
@@ -0,0 +1,115 @@
+! Reported as pr94070.
+! { dg-do run }
+! { dg-additional-sources "cf-out-descriptor-6-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks passing an assumed-size array as an intent(out)
+! argument to a bind (c) Fortran function from both C and Fortran.
+
+! Assumed-size arrays are not passed by descriptor. What we'll do
+! for this test function is pass the assumed-size array as the actual
+! argument corresponding to an assumed-rank dummy. This is supposed to
+! fill in the descriptor with information about the array present at
+! the call site.
+
+subroutine ftest (a, n) bind (c, name="ftest")
+ use iso_c_binding
+ integer(C_INT), intent(out) :: a(..)
+ integer(C_INT), value :: n
+ integer :: i
+
+ ! TS 29113
+ ! 6.4.2 SIZE
+ ! (1) for an assumed-rank object that is associated with an
+ ! assumed-size array, the result has the value −1 if DIM is
+ ! present and equal to the rank of ARRAY
+ if (rank (a) .ne. 1) stop 102
+ if (size (a, rank (a)) .ne. -1) stop 100
+ if (lbound (a, rank (a)) .ne. 1) stop 101
+
+ select rank (a)
+ rank (*)
+ do i = 1, n
+ a(i) = i
+ end do
+ rank default
+ stop 102
+ end select
+end subroutine
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a, n) bind (c, name="ctest")
+ use iso_c_binding
+ integer(C_INT), intent(out) :: a(..)
+ integer(C_INT), value :: n
+ end subroutine
+ subroutine ftest (a, n) bind (c, name="ftest")
+ use iso_c_binding
+ integer(C_INT), intent(out) :: a(..)
+ integer(C_INT), value :: n
+ end subroutine
+ end interface
+
+ integer(C_INT), target :: aa(10)
+
+ ! To get an assumed-size array descriptor, we have to first pass the
+ ! fixed-size array to a Fortran function with an assumed-size dummy,
+ call ftest1 (aa, 10) ! calls ftest
+ call ftest2 (aa, 10) ! has c binding, calls ftest
+ call ftest3 (aa, 10) ! calls ctest -> ftest
+ call ftest4 (aa, 10) ! has c binding, calls ctest -> ftest
+
+contains
+
+ subroutine ftest1 (a, n)
+ use iso_c_binding
+ integer(C_INT), intent(out) :: a(*)
+ integer(C_INT), value :: n
+ integer :: i
+ a(1:n) = 0
+ call ftest (a, n)
+ do i = 1, n
+ if (a (i) .ne. i) stop 200
+ end do
+ end subroutine
+
+ subroutine ftest2 (a, n) bind (c)
+ use iso_c_binding
+ integer(C_INT), intent(out) :: a(*)
+ integer(C_INT), value :: n
+ integer :: i
+ a(1:n) = 0
+ call ftest (a, n)
+ do i = 1, n
+ if (a (i) .ne. i) stop 201
+ end do
+ end subroutine
+
+ subroutine ftest3 (a, n)
+ use iso_c_binding
+ integer(C_INT), intent(out) :: a(*)
+ integer(C_INT), value :: n
+ integer :: i
+ a(1:n) = 0
+ call ctest (a, n)
+ do i = 1, n
+ if (a (i) .ne. i) stop 202
+ end do
+ end subroutine
+
+ subroutine ftest4 (a, n) bind (c)
+ use iso_c_binding
+ integer(C_INT), intent(out) :: a(*)
+ integer(C_INT), value :: n
+ integer :: i
+ a(1:n) = 0
+ call ctest (a, n)
+ do i = 1, n
+ if (a (i) .ne. i) stop 203
+ end do
+ end subroutine
+end program
Index: Fortran/gfortran/regression/c-interop/contiguous-1-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/contiguous-1-c.c
@@ -0,0 +1,56 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest1 (CFI_cdesc_t *a);
+extern void ctest2 (CFI_cdesc_t *a);
+
+static void
+ctest (CFI_cdesc_t *a)
+{
+ int i;
+ int *p;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* Make sure we got a valid descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].sm != sizeof(int))
+ abort ();
+ if (!CFI_is_contiguous (a))
+ abort ();
+
+ /* Negate the elements of the array. */
+ p = (int *)a->base_addr;
+ for (i = 0; i < a->dim[0].extent; i++)
+ p[i] = -p[i];
+}
+
+
+/* The two entry points are declared differently on the C side, but both
+ should do the same thing. */
+
+void
+ctest1 (CFI_cdesc_t *a)
+{
+ ctest (a);
+}
+
+void
+ctest2 (CFI_cdesc_t *a)
+{
+ ctest (a);
+}
+
Index: Fortran/gfortran/regression/c-interop/contiguous-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/contiguous-1.f90
@@ -0,0 +1,67 @@
+! { dg-do run }
+! { dg-additional-sources "contiguous-1-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! TS 29113
+! 8.7 In an invocation of an interoperable procedure whose Fortran
+! interface has an assumed-shape or assumed-rank dummy argument with the
+! CONTIGUOUS attribute, the associated effective argument may be an
+! array that is not contiguous or the address of a C descriptor for such
+! an array. If the procedure is invoked from Fortran or the procedure is
+! a Fortran procedure, the Fortran processor will handle the difference
+! in contiguity. If the procedure is invoked from C and the procedure is
+! a C procedure, the C code within the procedure shall be prepared to
+! handle the situation of receiving a discontiguous argument.
+!
+! This program tests the cases where Fortran code passes a non-contiguous
+! array section to a C function whose interface has the contiguous
+! attribute.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ ! ctest1 and ctest2 both negate the elements of their input array.
+ subroutine ctest1 (a) bind (c)
+ use iso_c_binding
+ integer(C_INT), contiguous :: a(:)
+ end subroutine
+ subroutine ctest2 (a) bind (c)
+ use iso_c_binding
+ integer(C_INT), contiguous :: a(..)
+ end subroutine
+ end interface
+
+ integer(C_INT) :: aa(32)
+ integer :: i
+
+ ! assumed-shape
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ctest1 (aa(4:12:2))
+ do i = 1, 32
+ if (i .ge. 4 .and. i .le. 12 .and. mod (i-4,2) .eq. 0) then
+ if (aa (i) .ne. -i) stop 101
+ else
+ if (aa (i) .ne. i) stop 102
+ end if
+ end do
+
+ ! assumed-rank
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ctest2 (aa(7:19:3))
+ do i = 1, 32
+ if (i .ge. 7 .and. i .le. 19 .and. mod (i-7,3) .eq. 0) then
+ if (aa (i) .ne. -i) stop 201
+ else
+ if (aa (i) .ne. i) stop 202
+ end if
+ end do
+
+end program
+
+
Index: Fortran/gfortran/regression/c-interop/contiguous-2-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/contiguous-2-c.c
@@ -0,0 +1,113 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest1 (CFI_cdesc_t *a);
+extern void ctest2 (CFI_cdesc_t *a);
+extern void ftest1 (CFI_cdesc_t *a, int first, int last, int step);
+extern void ftest2 (CFI_cdesc_t *a, int first, int last, int step);
+
+#if 0
+static void
+dump_array (CFI_cdesc_t *a, const char *name, const char *note)
+{
+ int i;
+
+ fprintf (stderr, "%s\n", note);
+ for (i = 0; i < a->dim[0].extent; i++)
+ {
+ int j = i + a->dim[0].lower_bound;
+ int elt;
+ CFI_index_t sub[1];
+ sub[0] = j;
+ elt = *((int *) CFI_address (a, sub));
+ fprintf (stderr, "%s[%d] = %d\n", name, j, elt);
+ }
+ fprintf (stderr, "\n");
+}
+#else
+#define dump_array(a, name, note)
+#endif
+
+static void
+ctest (CFI_cdesc_t *a, int lb, int ub, int s,
+ void (*fn) (CFI_cdesc_t *, int, int, int))
+{
+ CFI_CDESC_T(1) bdesc;
+ CFI_cdesc_t *b = (CFI_cdesc_t *) &bdesc;
+ CFI_index_t lb_array[1], ub_array[1], s_array[1];
+ int i;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* Make sure we got a valid descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+
+ /* Create an array section and pass it to fn. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (b, NULL, CFI_attribute_other,
+ CFI_type_int,
+ sizeof (int), 1, NULL));
+ lb_array[0] = lb - 1 + a->dim[0].lower_bound;
+ ub_array[0] = ub - 1 + a->dim[0].lower_bound;
+ s_array[0] = s;
+ check_CFI_status ("CFI_section",
+ CFI_section (b, a, lb_array, ub_array, s_array));
+ dump_CFI_cdesc_t (b);
+ dump_array (b, "b", "b after CFI_section");
+
+ /* Pass it to the Fortran function fn. */
+ if (CFI_is_contiguous (b))
+ abort ();
+ (*fn) (b, lb, ub, s);
+ dump_CFI_cdesc_t (b);
+ dump_array (b, "b", "b after calling Fortran fn");
+
+ /* fn is supposed to negate the elements of the array section it
+ receives. Check that the original array has been updated. */
+ dump_array (a, "a", "a after calling Fortran fn");
+ for (i = 0; i < a->dim[0].extent; i++)
+ {
+ int elt;
+ int j = i + a->dim[0].lower_bound;
+ CFI_index_t sub[1];
+ sub[0] = j;
+ elt = *((int *) CFI_address (a, sub));
+ if (i + 1 >= lb && i + 1 <= ub && (i + 1 - lb) % s == 0)
+ {
+ if (elt != - (i + 1))
+ abort ();
+ }
+ else if (elt != (i + 1))
+ abort ();
+ }
+}
+
+
+/* Entry points for the Fortran side. */
+
+void
+ctest1 (CFI_cdesc_t *a)
+{
+ ctest (a, 5, 13, 2, ftest1);
+}
+
+void
+ctest2 (CFI_cdesc_t *a)
+{
+ ctest (a, 8, 20, 3, ftest2);
+}
+
Index: Fortran/gfortran/regression/c-interop/contiguous-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/contiguous-2.f90
@@ -0,0 +1,152 @@
+! PR 101304
+! { dg-do run }
+! { dg-additional-sources "contiguous-2-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! TS 29113
+! 8.7 In an invocation of an interoperable procedure whose Fortran
+! interface has an assumed-shape or assumed-rank dummy argument with the
+! CONTIGUOUS attribute, the associated effective argument may be an
+! array that is not contiguous or the address of a C descriptor for such
+! an array. If the procedure is invoked from Fortran or the procedure is
+! a Fortran procedure, the Fortran processor will handle the difference
+! in contiguity. If the procedure is invoked from C and the procedure is
+! a C procedure, the C code within the procedure shall be prepared to
+! handle the situation of receiving a discontiguous argument.
+!
+! The wording is different in the 2018 standard, but the intent is more
+! or less the same:
+!
+! When an interoperable Fortran procedure that is invoked from C has a
+! dummy argument with the CONTIGUOUS attribute or that is an assumed-length
+! CHARACTER explicit-shape or assumed-size array, and the actual argument
+! is the address of a C descriptor for a discontiguous object, the Fortran
+! processor shall handle the difference in contiguity.
+!
+! This program tests the cases where a Fortran procedure with C binding and
+! a dummy array argument with the contiguous attribute is invoked from
+! both C or Fortran.
+
+! ftest1 and ftest2 both negate the elements of their input array;
+! this allows testing that modifications to the array contents get
+! propagated back to the base array.
+
+module m
+
+ contains
+
+ subroutine ftest1 (a, first, last, step) bind (c)
+ use iso_c_binding
+ integer(C_INT), contiguous :: a(:)
+ integer(C_INT), value :: first, last, step
+ integer :: i, ival
+
+ ! Sanity checking that we got a contiguous array. The direct call
+ ! to is_contiguous might be optimized away, but the indirect one
+ ! in check_contiguous shouldn't be.
+ ! FIXME: is this correct? "the Fortran processor will handle the
+ ! difference in contiguity" may not mean that it's required to make
+ ! the array contiguous, just that it can access it correctly?
+ if (.not. is_contiguous (a)) stop 301
+ call check_contiguous (a)
+
+ ! Sanity checking that we got the right input array contents.
+ ! print *, 'a on entry to ftest1'
+ ! do i = lbound(a, 1), ubound(a, 1)
+ ! print *, 'a(', i, ') = ', a(i)
+ ! end do
+ ival = first
+ do i = lbound(a, 1), ubound(a, 1)
+ if (a (i) .ne. ival) then
+ print *, 'a(', i, ') = ', a(i), ' expected ', ival
+ stop 302
+ end if
+ a(i) = - a(i)
+ ival = ival + step
+ end do
+ end subroutine
+
+ subroutine ftest2 (a, first, last, step) bind (c)
+ use iso_c_binding
+
+ integer(C_INT), contiguous :: a(..)
+ integer(C_INT), value :: first, last, step
+
+ select rank (a)
+ rank (1)
+ call ftest1 (a(:), first, last, step)
+ rank default
+ stop 303
+ end select
+ end subroutine
+
+ subroutine check_contiguous (a)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ if (.not. is_contiguous (a)) stop 304
+ end subroutine
+
+end module
+
+
+program testit
+ use iso_c_binding
+ use m
+ implicit none
+
+ interface
+ subroutine ctest1 (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(:)
+ end subroutine
+ subroutine ctest2 (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ end subroutine
+ end interface
+
+ integer(C_INT) :: aa(32)
+ integer :: i
+
+ ! assumed-shape, called from Fortran
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ftest1 (aa(4:12:2), 4, 12, 2)
+ do i = 1, 32
+ if (i .ge. 4 .and. i .le. 12 .and. mod (i-4,2) .eq. 0) then
+ if (aa (i) .ne. -i) stop 101
+ else
+ if (aa (i) .ne. i) stop 102
+ end if
+ end do
+
+ ! assumed-shape, called from C code which will use the C interface
+ ! to create a non-contiguous array section and pass it to ftest1.
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ctest1 (aa)
+
+ ! assumed-rank, called from Fortran
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ftest2 (aa(7:19:3), 7, 19, 3)
+ do i = 1, 32
+ if (i .ge. 7 .and. i .le. 19 .and. mod (i-7,3) .eq. 0) then
+ if (aa (i) .ne. -i) stop 201
+ else
+ if (aa (i) .ne. i) stop 202
+ end if
+ end do
+
+ ! assumed-rank, called from C code which will use the C interface
+ ! to create a non-contiguous array section and pass it to ftest2.
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ctest2 (aa)
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/contiguous-3-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/contiguous-3-c.c
@@ -0,0 +1,80 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest1 (CFI_cdesc_t *a, int first, int last, int step);
+extern void ctest2 (CFI_cdesc_t *a, int first, int last, int step);
+extern void ftest1 (CFI_cdesc_t *a, int first, int last, int step);
+extern void ftest2 (CFI_cdesc_t *a, int first, int last, int step);
+
+#if 0
+static void
+dump_array (CFI_cdesc_t *a, const char *name, const char *note)
+{
+ int i;
+
+ fprintf (stderr, "%s\n", note);
+ for (i = 0; i < a->dim[0].extent; i++)
+ {
+ int j = i + a->dim[0].lower_bound;
+ int elt;
+ CFI_index_t sub[1];
+ sub[0] = j;
+ elt = *((int *) CFI_address (a, sub));
+ fprintf (stderr, "%s[%d] = %d\n", name, j, elt);
+ }
+ fprintf (stderr, "\n");
+}
+#else
+#define dump_array(a, name, note)
+#endif
+
+static void
+ctest (CFI_cdesc_t *a, int first, int last, int step,
+ void (*fn) (CFI_cdesc_t *, int, int, int))
+{
+ int i;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+ dump_array (a, "a", "a on input to ctest");
+
+ /* Make sure we got a valid descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+
+ /* Pass it to the Fortran function fn. */
+ (*fn) (a, first, last, step);
+ dump_CFI_cdesc_t (a);
+ dump_array (a, "a", "a after calling Fortran fn");
+}
+
+/* Entry points for the Fortran side.
+ Note that the Fortran code has already created the array section
+ and these functions were declared without the CONTIGUOUS attribute
+ so they receive a non-contiguous array. The magic is supposed to
+ happen when we pass them back into a Fortran function declared with
+ the CONTIGUOUS attribute. */
+
+void
+ctest1 (CFI_cdesc_t *a, int first, int last, int step)
+{
+ ctest (a, first, last, step, ftest1);
+}
+
+void
+ctest2 (CFI_cdesc_t *a, int first, int last, int step)
+{
+ ctest (a, first, last, step, ftest2);
+}
Index: Fortran/gfortran/regression/c-interop/contiguous-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/contiguous-3.f90
@@ -0,0 +1,171 @@
+! PR 101304
+! { dg-do run }
+! { dg-additional-sources "contiguous-3-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! TS 29113
+! 8.7 In an invocation of an interoperable procedure whose Fortran
+! interface has an assumed-shape or assumed-rank dummy argument with the
+! CONTIGUOUS attribute, the associated effective argument may be an
+! array that is not contiguous or the address of a C descriptor for such
+! an array. If the procedure is invoked from Fortran or the procedure is
+! a Fortran procedure, the Fortran processor will handle the difference
+! in contiguity. If the procedure is invoked from C and the procedure is
+! a C procedure, the C code within the procedure shall be prepared to
+! handle the situation of receiving a discontiguous argument.
+!
+! The wording is different in the 2018 standard, but the intent is more
+! or less the same:
+!
+! When an interoperable Fortran procedure that is invoked from C has a
+! dummy argument with the CONTIGUOUS attribute or that is an assumed-length
+! CHARACTER explicit-shape or assumed-size array, and the actual argument
+! is the address of a C descriptor for a discontiguous object, the Fortran
+! processor shall handle the difference in contiguity.
+!
+! This program tests the cases where a Fortran procedure with C binding and
+! a dummy array argument with the contiguous attribute is invoked from
+! both C or Fortran. It is similar to contiguous-2.f90 but here the array
+! sections are created in Fortran even in the called-from-C case, rather
+! than by calling CFI_section.
+
+! ftest1 and ftest2 both negate the elements of their input array;
+! this allows testing that modifications to the array contents get
+! propagated back to the base array.
+
+module m
+
+ contains
+
+ subroutine ftest1 (a, first, last, step) bind (c)
+ use iso_c_binding
+ integer(C_INT), contiguous :: a(:)
+ integer(C_INT), value :: first, last, step
+ integer :: i, ival
+
+ ! Sanity checking that we got a contiguous array. The direct call
+ ! to is_contiguous might be optimized away, but the indirect one
+ ! in check_contiguous shouldn't be.
+ ! FIXME: is this correct? "the Fortran processor will handle the
+ ! difference in contiguity" may not mean that it's required to make
+ ! the array contiguous, just that it can access it correctly?
+ if (.not. is_contiguous (a)) stop 301
+ call check_contiguous (a)
+
+ ! Sanity checking that we got the right input array contents.
+ ! print *, 'a on entry to ftest1'
+ ! do i = lbound(a, 1), ubound(a, 1)
+ ! print *, 'a(', i, ') = ', a(i)
+ ! end do
+ ival = first
+ do i = lbound(a, 1), ubound(a, 1)
+ if (a (i) .ne. ival) then
+ print *, 'a(', i, ') = ', a(i), ' expected ', ival
+ stop 302
+ end if
+ a(i) = - a(i)
+ ival = ival + step
+ end do
+ end subroutine
+
+ subroutine ftest2 (a, first, last, step) bind (c)
+ use iso_c_binding
+
+ integer(C_INT), contiguous :: a(..)
+ integer(C_INT), value :: first, last, step
+
+ select rank (a)
+ rank (1)
+ call ftest1 (a(:), first, last, step)
+ rank default
+ stop 303
+ end select
+ end subroutine
+
+ subroutine check_contiguous (a)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ if (.not. is_contiguous (a)) stop 304
+ end subroutine
+
+end module
+
+
+program testit
+ use iso_c_binding
+ use m
+ implicit none
+
+ ! Note ctest1 and ctest2 do not have the contiguous attribute on a.
+ interface
+ subroutine ctest1 (a, first, last, step) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(:)
+ integer(C_INT), value :: first, last, step
+ end subroutine
+ subroutine ctest2 (a, first, last, step) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ integer(C_INT), value :: first, last, step
+ end subroutine
+ end interface
+
+ integer(C_INT) :: aa(32)
+ integer :: i
+
+ ! assumed-shape, called from Fortran
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ftest1 (aa(4:12:2), 4, 12, 2)
+ do i = 1, 32
+ if (i .ge. 4 .and. i .le. 12 .and. mod (i-4,2) .eq. 0) then
+ if (aa (i) .ne. -i) stop 101
+ else
+ if (aa (i) .ne. i) stop 102
+ end if
+ end do
+
+ ! assumed-shape, called indirectly from C code, using an array
+ ! section created in Fortran instead of by CFI_section
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ctest1 (aa(5:13:2), 5, 13, 2)
+ do i = 1, 32
+ if (i .ge. 5 .and. i .le. 13 .and. mod (i-5,2) .eq. 0) then
+ if (aa (i) .ne. -i) stop 103
+ else
+ if (aa (i) .ne. i) stop 104
+ end if
+ end do
+
+ ! assumed-rank, called from Fortran
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ftest2 (aa(7:19:3), 7, 19, 3)
+ do i = 1, 32
+ if (i .ge. 7 .and. i .le. 19 .and. mod (i-7,3) .eq. 0) then
+ if (aa (i) .ne. -i) stop 201
+ else
+ if (aa (i) .ne. i) stop 202
+ end if
+ end do
+
+ ! assumed-rank, called indirectly from C code, using an array
+ ! section created in Fortran instead of by CFI_section
+ do i = 1, 32
+ aa(i) = i
+ end do
+ call ctest2 (aa(8:20:3), 8, 20, 3)
+ do i = 1, 32
+ if (i .ge. 8 .and. i .le. 20 .and. mod (i-8,3) .eq. 0) then
+ if (aa (i) .ne. -i) stop 203
+ else
+ if (aa (i) .ne. i) stop 204
+ end if
+ end do
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/deferred-character-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/deferred-character-1.f90
@@ -0,0 +1,76 @@
+! PR92482
+! { dg-do compile}
+!
+! TS 29113
+! 8.7 Interoperability of procedures and procedure interfaces
+!
+! If a dummy argument in an interoperable interface is of type
+! CHARACTER and is allocatable or a pointer, its character length shall
+! be deferred.
+!
+! This test checks that this error is diagnosed and is supposed to fail.
+
+module m
+ use iso_c_binding
+
+ interface
+
+ ! These are supposed to be OK
+ subroutine good1 (x, n) bind (c)
+ use iso_c_binding
+ character (kind=C_CHAR, len=:), allocatable :: x
+ integer(C_INT), value :: n
+ end subroutine
+ subroutine good2 (x, n) bind (c)
+ use iso_c_binding
+ character (kind=C_CHAR, len=:), pointer :: x
+ integer(C_INT), value :: n
+ end subroutine
+
+ ! These are supposed to fail.
+ subroutine bad1 (x, n) bind (c) ! { dg-error "must have deferred length" }
+ use iso_c_binding
+ character (kind=C_CHAR, len=*), allocatable :: x
+ integer(C_INT), value :: n
+ end subroutine
+ subroutine bad2 (x, n) bind (c) ! { dg-error "must have deferred length" }
+ use iso_c_binding
+ character (kind=C_CHAR, len=*), pointer :: x
+ integer(C_INT), value :: n
+ end subroutine
+
+ subroutine bad3 (x, n) bind (c) ! { dg-error "must have deferred length" }
+ use iso_c_binding
+ character (kind=C_CHAR, len=80), allocatable :: x
+ integer(C_INT), value :: n
+ end subroutine
+ subroutine bad4 (x, n) bind (c) ! { dg-error "must have deferred length" }
+ use iso_c_binding
+ character (kind=C_CHAR, len=80), pointer :: x
+ integer(C_INT), value :: n
+ end subroutine
+
+ subroutine bad5 (x, n) bind (c) ! { dg-error "must have deferred length" }
+ use iso_c_binding
+ character (kind=C_CHAR, len=1), allocatable :: x
+ integer(C_INT), value :: n
+ end subroutine
+ subroutine bad6 (x, n) bind (c) ! { dg-error "must have deferred length" }
+ use iso_c_binding
+ character (kind=C_CHAR, len=1), pointer :: x
+ integer(C_INT), value :: n
+ end subroutine
+
+ subroutine bad7 (x, n) bind (c) ! { dg-error "must have deferred length" }
+ use iso_c_binding
+ character (kind=C_CHAR), allocatable :: x
+ integer(C_INT), value :: n
+ end subroutine
+ subroutine bad8 (x, n) bind (c) ! { dg-error "must have deferred length" }
+ use iso_c_binding
+ character (kind=C_CHAR), pointer :: x
+ integer(C_INT), value :: n
+ end subroutine
+ end interface
+
+end module
Index: Fortran/gfortran/regression/c-interop/deferred-character-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/deferred-character-2.f90
@@ -0,0 +1,55 @@
+! PR 92482
+! { dg-do run }
+!
+! TS 29113
+! 8.7 Interoperability of procedures and procedure interfaces
+!
+! If a dummy argument in an interoperable interface is of type
+! CHARACTER and is allocatable or a pointer, its character length shall
+! be deferred.
+
+program testit
+ use iso_c_binding
+
+ character (kind=C_CHAR, len=:), allocatable :: aa
+ character (kind=C_CHAR, len=:), pointer :: pp
+
+
+ pp => NULL ()
+
+ call frobf (aa, pp)
+ if (.not. allocated (aa)) stop 101
+ if (aa .ne. 'foo') stop 102
+ if (.not. associated (pp)) stop 103
+ if (pp .ne. 'bar') stop 104
+
+ pp => NULL ()
+
+ call frobc (aa, pp)
+ if (.not. allocated (aa)) stop 101
+ if (aa .ne. 'frog') stop 102
+ if (.not. associated (pp)) stop 103
+ if (pp .ne. 'toad') stop 104
+
+
+ contains
+
+ subroutine frobf (a, p)
+ use iso_c_binding
+ character (kind=C_CHAR, len=:), allocatable :: a
+ character (kind=C_CHAR, len=:), pointer :: p
+ allocate (character(len=3) :: p)
+ a = 'foo'
+ p = 'bar'
+ end subroutine
+
+ subroutine frobc (a, p) bind (c)
+ use iso_c_binding
+ character (kind=C_CHAR, len=:), allocatable :: a
+ character (kind=C_CHAR, len=:), pointer :: p
+ allocate (character(len=4) :: p)
+ a = 'frog'
+ p = 'toad'
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/dump-descriptors.h
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/dump-descriptors.h
@@ -0,0 +1,12 @@
+/* Definitions of functions in dump-descriptors.c. */
+
+#include "ISO_Fortran_binding.h"
+
+extern void dump_CFI_cdesc_t (CFI_cdesc_t *d);
+extern void dump_CFI_dim_t (CFI_dim_t *d);
+extern void dump_CFI_attribute_t (CFI_attribute_t a);
+extern void dump_CFI_index_t (CFI_index_t i);
+extern void dump_CFI_rank_t (CFI_rank_t r);
+extern void dump_CFI_type_t (CFI_type_t t);
+
+void check_CFI_status (const char *fn, int code);
Index: Fortran/gfortran/regression/c-interop/dump-descriptors.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/dump-descriptors.c
@@ -0,0 +1,195 @@
+/* This file contains some useful routines for debugging problems with C
+ descriptors. Compiling it also acts as a test that the implementation of
+ ISO_Fortran_binding.h provides all the types and constants specified in
+ TS29113. */
+
+#include
+#include
+#include
+#include "dump-descriptors.h"
+
+void
+dump_CFI_cdesc_t (CFI_cdesc_t *d)
+{
+ fprintf (stderr, "base_addr, (long)(d->elem_len), d->version);
+ fprintf (stderr, "\n rank=");
+ dump_CFI_rank_t (d->rank);
+ fprintf (stderr, " type=");
+ dump_CFI_type_t (d->type);
+ fprintf (stderr, " attribute=");
+ dump_CFI_attribute_t (d->attribute);
+
+ /* Dimension info may not be initialized if it's an allocatable
+ or pointer descriptor with a null base_addr. */
+ if (d->rank > 0 && d->base_addr)
+ {
+ CFI_rank_t i;
+ for (i = 0; i < d->rank; i++)
+ {
+ if (i == 0)
+ fprintf (stderr, "\n dim=[");
+ else
+ fprintf (stderr, ",\n ");
+ dump_CFI_dim_t (d->dim + i);
+ }
+ fprintf (stderr, "]");
+ }
+ fprintf (stderr, ">\n");
+}
+
+void
+dump_CFI_dim_t (CFI_dim_t *d)
+{
+ fprintf (stderr, "");
+}
+
+void
+dump_CFI_attribute_t (CFI_attribute_t a)
+{
+ switch (a)
+ {
+ case CFI_attribute_pointer:
+ fprintf (stderr, "CFI_attribute_pointer");
+ break;
+ case CFI_attribute_allocatable:
+ fprintf (stderr, "CFI_attribute_allocatable");
+ break;
+ case CFI_attribute_other:
+ fprintf (stderr, "CFI_attribute_other");
+ break;
+ default:
+ fprintf (stderr, "unknown(%d)", (int)a);
+ break;
+ }
+}
+
+void
+dump_CFI_index_t (CFI_index_t i)
+{
+ fprintf (stderr, "%ld", (long)i);
+}
+
+void
+dump_CFI_rank_t (CFI_rank_t r)
+{
+ fprintf (stderr, "%d", (int)r);
+}
+
+/* We can't use a switch statement to dispatch CFI_type_t because
+ the type name macros may not be unique. Iterate over a table
+ instead. */
+
+struct type_name_map {
+ CFI_type_t t;
+ const char *n;
+};
+
+struct type_name_map type_names[] =
+{
+ { CFI_type_signed_char, "CFI_type_signed_char" },
+ { CFI_type_short, "CFI_type_short" },
+ { CFI_type_int, "CFI_type_int" },
+ { CFI_type_long, "CFI_type_long" },
+ { CFI_type_long_long, "CFI_type_long_long" },
+ { CFI_type_size_t, "CFI_type_size_t" },
+ { CFI_type_int8_t, "CFI_type_int8_t" },
+ { CFI_type_int16_t, "CFI_type_int16_t" },
+ { CFI_type_int32_t, "CFI_type_int32_t" },
+ { CFI_type_int64_t, "CFI_type_int64_t" },
+ { CFI_type_int_least8_t, "CFI_type_int_least8_t" },
+ { CFI_type_int_least16_t, "CFI_type_int_least16_t" },
+ { CFI_type_int_least32_t, "CFI_type_int_least32_t" },
+ { CFI_type_int_least64_t, "CFI_type_int_least64_t" },
+ { CFI_type_int_fast8_t, "CFI_type_int_fast8_t" },
+ { CFI_type_int_fast16_t, "CFI_type_int_fast16_t" },
+ { CFI_type_int_fast32_t, "CFI_type_int_fast32_t" },
+ { CFI_type_int_fast64_t, "CFI_type_int_fast64_t" },
+ { CFI_type_intmax_t, "CFI_type_intmax_t" },
+ { CFI_type_intptr_t, "CFI_type_intptr_t" },
+ { CFI_type_ptrdiff_t, "CFI_type_ptrdiff_t" },
+ { CFI_type_float, "CFI_type_float" },
+ { CFI_type_double, "CFI_type_double" },
+ { CFI_type_long_double, "CFI_type_long_double" },
+ { CFI_type_float_Complex, "CFI_type_float_Complex" },
+ { CFI_type_double_Complex, "CFI_type_double_Complex" },
+ { CFI_type_long_double_Complex, "CFI_type_long_double_Complex" },
+ { CFI_type_Bool, "CFI_type_Bool" },
+ { CFI_type_char, "CFI_type_char" },
+ { CFI_type_cptr, "CFI_type_cptr" },
+ { CFI_type_struct, "CFI_type_struct" },
+ { CFI_type_other, "CFI_type_other" },
+ /* Extension types */
+ { CFI_type_int128_t, "CFI_type_int128_t" },
+ { CFI_type_int_least128_t, "CFI_type_int_least128_t" },
+ { CFI_type_int_fast128_t, "CFI_type_int_fast128_t" },
+ { CFI_type_ucs4_char, "CFI_type_ucs4_char" },
+ { CFI_type_float128, "CFI_type_float128" },
+ { CFI_type_float128_Complex, "CFI_type_float128_Complex" },
+ { CFI_type_cfunptr, "CFI_type_cfunptr" }
+};
+
+void
+dump_CFI_type_t (CFI_type_t t)
+{
+ int i;
+ for (i = 0; i < sizeof (type_names) / sizeof (struct type_name_map); i++)
+ if (type_names[i].t == t)
+ {
+ fprintf (stderr, "%s", type_names[i].n);
+ return;
+ }
+ fprintf (stderr, "unknown(%d)", (int)t);
+}
+
+void
+check_CFI_status (const char *fn, int code)
+{
+ const char *msg;
+ switch (code)
+ {
+ case CFI_SUCCESS:
+ return;
+ case CFI_ERROR_BASE_ADDR_NULL:
+ msg = "CFI_ERROR_BASE_ADDR_NULL";
+ break;
+ case CFI_ERROR_BASE_ADDR_NOT_NULL:
+ msg = "CFI_ERROR_BASE_ADDR_NOT_NULL";
+ break;
+ case CFI_INVALID_ELEM_LEN:
+ msg = "CFI_INVALID_ELEM_LEN";
+ break;
+ case CFI_INVALID_RANK:
+ msg = "CFI_INVALID_RANK";
+ break;
+ case CFI_INVALID_TYPE:
+ msg = "CFI_INVALID_TYPE";
+ break;
+ case CFI_INVALID_ATTRIBUTE:
+ msg = "CFI_INVALID_ATTRIBUTE";
+ break;
+ case CFI_INVALID_EXTENT:
+ msg = "CFI_INVALID_EXTENT";
+ break;
+ case CFI_INVALID_DESCRIPTOR:
+ msg = "CFI_INVALID_DESCRIPTOR";
+ break;
+ case CFI_ERROR_MEM_ALLOCATION:
+ msg = "CFI_ERROR_MEM_ALLOCATION";
+ break;
+ case CFI_ERROR_OUT_OF_BOUNDS:
+ msg = "CFI_ERROR_OUT_OF_BOUNDS";
+ break;
+ default:
+ msg = "unknown error";
+ break;
+ }
+ fprintf (stderr, "%s returned %s\n", fn, msg);
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/establish-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/establish-c.c
@@ -0,0 +1,134 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+/* For simplicity, point descriptors at a static buffer. BUFSIZE should
+ be large enough for any of the standard types and we'll use DIM0 and DIM1
+ for array dimensions. */
+#define BUFSIZE 64
+#define DIM0 3
+#define DIM1 10
+#define ARRAYBUFSIZE BUFSIZE * DIM0 * DIM1
+static char *buf[ARRAYBUFSIZE] __attribute__ ((aligned (8)));
+static CFI_index_t extents[] = {DIM0, DIM1};
+
+/* Magic number to use for elem_len field. */
+#define MAGIC_ELEM_LEN 20
+
+struct tc_info
+{
+ CFI_type_t typecode;
+ char *name;
+ size_t size;
+};
+
+static struct tc_info tc_table[] =
+{
+ { CFI_type_signed_char, "CFI_type_signed_char", sizeof (signed char) },
+ { CFI_type_short, "CFI_type_short", sizeof (short) },
+ { CFI_type_int, "CFI_type_int", sizeof (int) },
+ { CFI_type_long, "CFI_type_long", sizeof (long) },
+ { CFI_type_long_long, "CFI_type_long_long", sizeof (long long) },
+ { CFI_type_size_t, "CFI_type_size_t", sizeof (size_t) },
+ { CFI_type_int8_t, "CFI_type_int8_t", sizeof (int8_t) },
+ { CFI_type_int16_t, "CFI_type_int16_t", sizeof (int16_t) },
+ { CFI_type_int32_t, "CFI_type_int32_t", sizeof (int32_t) },
+ { CFI_type_int64_t, "CFI_type_int64_t", sizeof (int64_t) },
+ { CFI_type_int_least8_t, "CFI_type_int_least8_t", sizeof (int_least8_t) },
+ { CFI_type_int_least16_t, "CFI_type_int_least16_t", sizeof (int_least16_t) },
+ { CFI_type_int_least32_t, "CFI_type_int_least32_t", sizeof (int_least32_t) },
+ { CFI_type_int_least64_t, "CFI_type_int_least64_t", sizeof (int_least64_t) },
+ { CFI_type_int_fast8_t, "CFI_type_int_fast8_t", sizeof (int_fast8_t) },
+ { CFI_type_int_fast16_t, "CFI_type_int_fast16_t", sizeof (int_fast16_t) },
+ { CFI_type_int_fast32_t, "CFI_type_int_fast32_t", sizeof (int_fast32_t) },
+ { CFI_type_int_fast64_t, "CFI_type_int_fast64_t", sizeof (int_fast64_t) },
+ { CFI_type_intmax_t, "CFI_type_intmax_t", sizeof (intmax_t) },
+ { CFI_type_intptr_t, "CFI_type_intptr_t", sizeof (intptr_t) },
+ { CFI_type_ptrdiff_t, "CFI_type_ptrdiff_t", sizeof (ptrdiff_t) },
+ { CFI_type_float, "CFI_type_float", sizeof (float) },
+ { CFI_type_double, "CFI_type_double", sizeof (double) },
+ { CFI_type_long_double, "CFI_type_long_double", sizeof (long double) },
+ { CFI_type_float_Complex, "CFI_type_float_Complex",
+ sizeof (float _Complex) },
+ { CFI_type_double_Complex, "CFI_type_double_Complex",
+ sizeof (double _Complex) },
+ { CFI_type_long_double_Complex, "CFI_type_long_double_Complex",
+ sizeof (long double _Complex) },
+ { CFI_type_Bool, "CFI_type_Bool", sizeof (_Bool) },
+ { CFI_type_char, "CFI_type_char", sizeof (char) },
+ { CFI_type_cptr, "CFI_type_cptr", sizeof (void *) },
+ { CFI_type_struct, "CFI_type_struct", 0 },
+ { CFI_type_other, "CFI_type_other", -1 }
+};
+
+int
+test_array (struct tc_info *tc, void *ptr, CFI_attribute_t attr)
+{
+ CFI_CDESC_T(2) desc;
+ CFI_cdesc_t *a = (CFI_cdesc_t *) &desc;
+ int bad = 0;
+ size_t elem_len;
+
+ /* Initialize the descriptor to garbage values so we can confirm it's
+ properly initialized with good ones later. */
+ memset (a, -1, sizeof(desc));
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (a, ptr, attr, tc->typecode,
+ MAGIC_ELEM_LEN, 2, extents));
+
+ /* elem_len is ignored unless type is CFI type struct, CFI type other,
+ or a character type. */
+ if (tc->typecode == CFI_type_char
+ || tc->typecode == CFI_type_struct
+ || tc->typecode == CFI_type_other)
+ elem_len = MAGIC_ELEM_LEN;
+ else
+ elem_len = tc->size;
+
+ if (a->elem_len != elem_len
+ || a->base_addr != ptr
+ || a->type != tc->typecode
+ || a->version != CFI_VERSION
+ || a->attribute != attr
+ || a->rank != 2
+ || (ptr &&
+ /* extents parameter is ignored if ptr is null */
+ (a->dim[0].lower_bound != 0
+ || a->dim[0].extent != DIM0
+ || a->dim[0].sm != elem_len
+ || a->dim[1].lower_bound != 0
+ || a->dim[1].extent != DIM1
+ || a->dim[1].sm != elem_len*DIM0)))
+ {
+ fprintf (stderr, "Bad array descriptor for %s:\n", tc->name);
+ dump_CFI_cdesc_t (a);
+ return 1;
+ }
+ return 0;
+}
+
+/* External entry point. */
+extern void ctest_establish (void);
+
+void
+ctest_establish (void)
+{
+ int ncodes = sizeof (tc_table) / sizeof (struct tc_info);
+ int i;
+ int bad = 0;
+
+ for (i = 0; i < ncodes; i++)
+ {
+ bad += test_array (&tc_table[i], (void *)buf, CFI_attribute_other);
+ bad += test_array (&tc_table[i], NULL, CFI_attribute_allocatable);
+ bad += test_array (&tc_table[i], (void *)buf, CFI_attribute_pointer);
+ }
+ if (bad)
+ abort ();
+}
+
Index: Fortran/gfortran/regression/c-interop/establish-errors-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/establish-errors-c.c
@@ -0,0 +1,120 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+/* For simplicity, point descriptors at a static buffer. BUFSIZE should
+ be large enough for any of the standard types and we'll use DIM0 and DIM1
+ for array dimensions. */
+#define BUFSIZE 64
+#define DIM0 3
+#define DIM1 10
+#define ARRAYBUFSIZE BUFSIZE * DIM0 * DIM1
+static char *buf[ARRAYBUFSIZE] __attribute__ ((aligned (8)));
+static CFI_index_t extents[] = {DIM0, DIM1};
+
+/* Magic number to use for elem_len field. */
+#define MAGIC_ELEM_LEN 20
+
+
+/* External entry point. */
+extern void ctest (void);
+
+void
+ctest (void)
+{
+ int bad = 0;
+ int status;
+ CFI_CDESC_T(2) desc;
+ CFI_cdesc_t *a = (CFI_cdesc_t *) &desc;
+
+ /* If the attribute argument is CFI_attribute_allocatable,
+ base_addr shall be a null pointer. */
+ status = CFI_establish (a, (void *)buf, CFI_attribute_allocatable,
+ CFI_type_int, 0, 2, extents);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for non-null pointer with CFI_attribute_allocatable\n");
+ bad ++;
+ }
+
+ /* type shall have the value of one of the type codes in Table 18.4,
+ or have a positive value corresponding to an interoperable C type. */
+ status = CFI_establish (a, (void *)buf, CFI_attribute_other,
+ CFI_type_other - 1, 0, 2, extents);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for invalid negative type code\n");
+ bad ++;
+ }
+
+ /* If the type is CFI_type_struct, CFI_type_other, or a Fortran
+ character type, elem_len shall be greater than zero and equal to
+ the storage size in bytes of an element of the object. */
+ status = CFI_establish (a, (void *)buf, CFI_attribute_other,
+ CFI_type_struct, 0, 2, extents);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for invalid size with CFI_type_struct\n");
+ bad ++;
+ }
+
+ status = CFI_establish (a, (void *)buf, CFI_attribute_other,
+ CFI_type_char, 0, 2, extents);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for invalid size with CFI_type_char\n");
+ bad ++;
+ }
+
+ /* Rank shall be between 0 and CFI_MAX_RANK inclusive. */
+ status = CFI_establish (a, NULL, CFI_attribute_allocatable,
+ CFI_type_int, 0, -1, extents);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for negative rank\n");
+ bad ++;
+ }
+ status = CFI_establish (a, NULL, CFI_attribute_allocatable,
+ CFI_type_int, 0, CFI_MAX_RANK + 1, extents);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for rank > CFI_MAX_RANK\n");
+ bad ++;
+ }
+
+ /* extents is ignored if the rank r is zero or if base_addr is a
+ null pointer. Otherwise, it shall be the address of an array... */
+ status = CFI_establish (a, (void *)buf, CFI_attribute_other,
+ CFI_type_int, 0, 2, NULL);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for null extents\n");
+ bad ++;
+ }
+
+ /* Extents shall all be nonnegative. */
+ extents[1] = -extents[1];
+ status = CFI_establish (a, (void *)buf, CFI_attribute_other,
+ CFI_type_int, 0, 2, extents);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for negative extents\n");
+ bad ++;
+ }
+
+ if (bad)
+ abort ();
+}
+
Index: Fortran/gfortran/regression/c-interop/establish-errors.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/establish-errors.f90
@@ -0,0 +1,30 @@
+! PR101317
+! { dg-do run }
+! { dg-additional-sources "establish-errors-c.c dump-descriptors.c" }
+! { dg-additional-options "-Wno-error -fcheck=all" }
+! { dg-warning "command-line option '-fcheck=all' is valid for Fortran but not for C" "" { target *-*-* } 0 }
+!
+! This program tests that the CFI_establish function properly detects
+! invalid arguments. All the interesting things happen in the
+! corresponding C code.
+!
+! The situation here seems to be that while TS29113 defines error codes
+! for CFI_establish, it doesn't actually require the implementation to detect
+! those errors by saying the arguments "shall be" such-and-such, e.g. it is
+! undefined behavior if they are not. In gfortran you can enable some
+! run-time checking by building with -fcheck=all.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+
+ subroutine ctest () bind (c)
+ end subroutine
+
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/establish.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/establish.f90
@@ -0,0 +1,35 @@
+! PR 101305
+! { dg-do run }
+! { dg-additional-sources "establish-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests the CFI_establish function. All the interesting
+! things happen in the corresponding C code.
+
+! Eventually we might want to make the C code pass the descriptors back to
+! C-callable Fortran functions, but for now it just checks them internally.
+
+module mm
+ use iso_c_binding
+
+ type, bind (c) :: s
+ integer(C_INT) :: i, j
+ end type
+end module
+
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+
+ subroutine ctest_establish () bind (c)
+ end subroutine
+
+ end interface
+
+ call ctest_establish ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/explicit-interface.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/explicit-interface.f90
@@ -0,0 +1,60 @@
+! { dg-do compile }
+!
+! TS 29113
+! 6.2 Explicit interface
+!
+! Additionally to the rules of subclause 12.4.2.2 of ISO/IEC 1539-1:2010,
+! a procedure shall have an explicit interface if it has a dummy argument
+! that is assumed-rank.
+!
+! NOTE 6.1
+! An explicit interface is also required for a procedure if it has a
+! dummy argument that is assumed-type because an assumed-type dummy
+! argument is polymorphic.
+!
+! This file contains code that is expected to produce errors.
+
+module m1
+
+ interface
+
+ subroutine s1 (a)
+ integer :: a(..)
+ end subroutine
+
+ subroutine s2 (b)
+ type(*) :: b
+ end subroutine
+
+ end interface
+
+end module
+
+module m2
+
+ contains
+
+ ! This subroutine has an explicit interface, and so do the things
+ ! it calls.
+ subroutine good (a, b)
+ use m1
+ integer :: a(..)
+ type (*) :: b
+
+ call s1 (a)
+ call s2 (b)
+ end subroutine
+
+ ! This subroutine has an explicit interface, but the things it calls don't.
+ subroutine bad (a, b)
+ use m1
+ integer :: a(..)
+ type (*) :: b
+ external :: s3, s4
+
+ call s3 (a) ! { dg-error "Assumed-rank argument" }
+ call s4 (b) ! { dg-error "Assumed-type argument" }
+ end subroutine
+
+end module
+
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-1-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-1-c.c
@@ -0,0 +1,46 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+
+void
+ctest (CFI_cdesc_t *a)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* The actual argument on the Fortran side was declared as
+ integer(C_INT) :: aa(10,-1:3)
+ Make sure that matches what's in the descriptor. Note that per
+ section 18.5.3 in the 2018 standard, for a nonallocatable nonpointer
+ array, the array dimensions in the descriptor reflect the shape of
+ the array rather than the actual bounds; the lower_bound is required
+ to be zero. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 2)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != 10)
+ abort ();
+ if (a->dim[0].sm != sizeof(int))
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != 5)
+ abort ();
+ if (a->dim[1].sm != a->dim[0].extent * sizeof(int))
+ abort ();
+ if (!CFI_is_contiguous (a))
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-1.f90
@@ -0,0 +1,34 @@
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-1-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This checks that a C function declared to have an assumed-shape array
+! argument can be called from Fortran and receives a correct descriptor.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(:,:)
+ end subroutine
+ end interface
+
+ integer(C_INT) :: aa(10,-1:3)
+
+ ! Test both passing the fixed-size array directly to the function
+ ! with a C interface, and indirectly via a Fortran function with an
+ ! assumed-shape dummy argument.
+ call ctest (aa)
+ call ftest (aa)
+
+contains
+ subroutine ftest (a)
+ use iso_c_binding
+ integer(C_INT) :: a(:,:)
+ call ctest (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-2-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-2-c.c
@@ -0,0 +1,68 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, int n);
+
+void
+ctest (CFI_cdesc_t *a, int n)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(float))
+ abort ();
+ if (a->type != CFI_type_float)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+
+ if (n == 1)
+ {
+ /* The actual argument on the Fortran side was declared as
+ real(C_FLOAT):: aa(100) */
+ if (a->rank != 1)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != 100)
+ abort ();
+ if (a->dim[0].sm != sizeof(float))
+ abort ();
+ if (!CFI_is_contiguous (a))
+ abort ();
+ }
+ else if (n == 3)
+ {
+ /* The actual argument on the Fortran side was declared as
+ real(C_FLOAT) :: bb(3,4,5) */
+ if (a->rank != 3)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != 3)
+ abort ();
+ if (a->dim[0].sm != sizeof(float))
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != 4)
+ abort ();
+ if (a->dim[1].sm != a->dim[0].sm * a->dim[0].extent)
+ abort ();
+ if (a->dim[2].lower_bound != 0)
+ abort ();
+ if (a->dim[2].extent != 5)
+ abort ();
+ if (a->dim[2].sm != a->dim[1].sm * a->dim[1].extent)
+ abort ();
+ if (!CFI_is_contiguous (a))
+ abort ();
+ }
+ else
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-2.f90
@@ -0,0 +1,40 @@
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-2-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that a C function declared to take an assumed-rank
+! array argument can be called from Fortran, and receives a correct
+! descriptor.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a, n) bind (c)
+ use iso_c_binding
+ real(C_FLOAT) :: a(..)
+ integer(C_INT), value :: n
+ end subroutine
+ end interface
+
+ real(C_FLOAT) :: aa(100)
+ real(C_FLOAT) :: bb(3,4,5)
+
+ ! Test both passing the fixed-size array directly to the function
+ ! with a C interface, and indirectly via a Fortran function with an
+ ! assumed-rank dummy argument.
+ call ctest (aa, 1)
+ call ctest (bb, 3)
+ call ftest (aa, 1)
+ call ftest (bb, 3)
+
+contains
+ subroutine ftest (a, n)
+ use iso_c_binding
+ real(C_FLOAT) :: a(..)
+ integer, value :: n
+ call ctest (a, n)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-3-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-3-c.c
@@ -0,0 +1,42 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, CFI_cdesc_t *b, int initp);
+
+void
+ctest (CFI_cdesc_t *a, CFI_cdesc_t *b, int initp)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+ dump_CFI_cdesc_t (b);
+
+ /* Make sure the descriptors match what we are expecting. a is an
+ allocatable derived type object, b is a pointer which points at a
+ if initp is true. */
+ if (initp && !a->base_addr)
+ abort ();
+ else if (!initp && a->base_addr)
+ abort ();
+ if (a->base_addr != b->base_addr)
+ abort ();
+
+ if (a->rank != 0)
+ abort ();
+ if (b->rank != 0)
+ abort ();
+ if (a->type != CFI_type_struct)
+ abort ();
+ if (b->type != CFI_type_struct)
+ abort ();
+ if (a->elem_len != 3 * 3 * sizeof(double))
+ abort ();
+ if (b->elem_len != 3 * 3 * sizeof(double))
+ abort ();
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (b->attribute != CFI_attribute_pointer)
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-3.f90
@@ -0,0 +1,37 @@
+! PR 101308
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-3-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that pointer and allocatable scalar arguments are
+! correctly passed by descriptor from Fortran code into C.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ type, bind (c) :: m
+ real(C_DOUBLE) :: a(3, 3)
+ end type
+
+ interface
+ subroutine ctest (a, b, initp) bind (c)
+ use iso_c_binding
+ import m
+ type(m), allocatable :: a
+ type(m), pointer :: b
+ integer(C_INT), value :: initp
+ end subroutine
+ end interface
+
+ type (m), allocatable, target :: aa
+ type (m), pointer :: bb
+
+ ! Test both before and after allocation/pointer initialization.
+ bb => null()
+ call ctest (aa, bb, 0)
+ allocate (aa)
+ bb => aa
+ call ctest (aa, bb, 1)
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-4-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-4-c.c
@@ -0,0 +1,57 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, CFI_cdesc_t *b, int initp);
+
+void
+ctest (CFI_cdesc_t *a, CFI_cdesc_t *b, int initp)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+ dump_CFI_cdesc_t (b);
+
+ /* Make sure the descriptors match what we are expecting. a is an
+ allocatable derived type object, b is a pointer which points at a
+ if initp is true. */
+ if (initp && !a->base_addr)
+ abort ();
+ else if (!initp && a->base_addr)
+ abort ();
+ if (a->base_addr != b->base_addr)
+ abort ();
+
+ if (a->type != CFI_type_struct)
+ abort ();
+ if (b->type != CFI_type_struct)
+ abort ();
+ if (a->elem_len != 3 * 3 * sizeof(double))
+ abort ();
+ if (b->elem_len != 3 * 3 * sizeof(double))
+ abort ();
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (b->attribute != CFI_attribute_pointer)
+ abort ();
+
+ if (initp)
+ /* The actual array is allocated with
+ allocate (aa(3:7))
+ Per 8.3.3 of TS29113, the lower_bound must reflect that. */
+ {
+ if (a->rank != 1)
+ abort ();
+ if (b->rank != 1)
+ abort ();
+ if (a->dim[0].lower_bound != 3)
+ abort ();
+ if (b->dim[0].lower_bound != 3)
+ abort ();
+ if (a->dim[0].extent != 5)
+ abort ();
+ if (b->dim[0].extent != 5)
+ abort ();
+ }
+}
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-4.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-4-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that pointer and allocatable array arguments are
+! correctly passed by descriptor from Fortran code into C.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ type, bind (c) :: m
+ real(C_DOUBLE) :: a(3, 3)
+ end type
+
+ interface
+ subroutine ctest (a, b, initp) bind (c)
+ use iso_c_binding
+ import m
+ type(m), allocatable :: a(:)
+ type(m), pointer :: b(:)
+ integer(C_INT), value :: initp
+ end subroutine
+ end interface
+
+ type (m), allocatable, target :: aa(:)
+ type (m), pointer :: bb(:)
+
+ ! Test both before and after allocation/pointer initialization.
+ bb => NULL ()
+ call ctest (aa, bb, 0)
+ allocate (aa(3:7))
+ bb => aa
+ call ctest (aa, bb, 1)
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-5-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-5-c.c
@@ -0,0 +1,28 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+
+void
+ctest (CFI_cdesc_t *a)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* The actual argument on the Fortran side was declared as
+ character(len=20) :: aa
+ Make sure that matches what's in the descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != 20)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (a->type != CFI_type_char)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-5.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-5.f90
@@ -0,0 +1,35 @@
+! PR92482
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-5-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests it works to call a C function from Fortran with
+! an assumed length character dummy.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ character(len=*,kind=C_CHAR) :: a
+ end subroutine
+ end interface
+
+ character(len=20,kind=C_CHAR) :: aa
+
+ ! Test both passing the fixed-length string directly to the function
+ ! with a C interface, and indirectly via a Fortran function with an
+ ! assumed-length dummy argument.
+ call ctest (aa)
+ call ftest (aa)
+
+contains
+ subroutine ftest (a)
+ use iso_c_binding
+ character(len=*,kind=C_CHAR) :: a
+ call ctest (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-6-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-6-c.c
@@ -0,0 +1,51 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+
+void
+ctest (CFI_cdesc_t *a)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* The actual argument on the Fortran side was declared as
+ integer(C_INT) :: aa(10,5:8)
+ but was passed via other functions that variously describe it as
+ having size (10,*), (10,1:*), or (10,5:*). But, the spec says:
+
+ For a C descriptor of a nonallocatable nonpointer object, the
+ value of the lower_bound member of each element of the dim member
+ of the descriptor is zero.
+
+ In a C descriptor of an assumed-size array, the extent member of
+ the last element of the dim member has the value −1. */
+
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 2)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != 10)
+ abort ();
+ if (a->dim[0].sm != sizeof(int))
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != -1)
+ abort ();
+ if (a->dim[1].sm != a->dim[0].extent * sizeof(int))
+ abort ();
+}
+
+
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-6.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-6.f90
@@ -0,0 +1,50 @@
+! Reported as pr94070.
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-6-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that an assumed-size array argument can be passed
+! to a C function via a descriptor, and that the argument descriptor
+! received by C correctly identifies it as assumed-size.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ ! Assumed-size arrays are not passed by descriptor. What we'll do
+ ! for this test function is bind an assumed-rank dummy
+ ! to the assumed-size array. This is supposed to fill in the descriptor
+ ! with information about the array present at the call site.
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ end subroutine
+ end interface
+
+ integer(C_INT), target :: aa(10,5:8)
+
+ ! To get an assumed-size array descriptor, we have to first pass the
+ ! fixed-size array to a Fortran function with an assumed-size dummy,
+ call ftest1 (aa)
+ call ftest2 (aa)
+ call ftest3 (aa)
+
+contains
+ subroutine ftest1 (a)
+ use iso_c_binding
+ integer(C_INT) :: a(10,*)
+ call ctest (a)
+ end subroutine
+ subroutine ftest2 (a)
+ use iso_c_binding
+ integer(C_INT) :: a(10,5:*)
+ call ctest (a)
+ end subroutine
+ subroutine ftest3 (a)
+ use iso_c_binding
+ integer(C_INT) :: a(10,1:*)
+ call ctest (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-7-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-7-c.c
@@ -0,0 +1,53 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *, _Bool);
+
+void
+ctest (CFI_cdesc_t *a, _Bool is_cont)
+{
+ CFI_index_t subscripts[2];
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+
+#if DEBUG
+ dump_CFI_cdesc_t (a);
+#endif
+
+ /* We expect to get an array of shape (5,10) that may not be
+ contiguous. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 2)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != 5)
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != 10)
+ abort ();
+
+ if (is_cont != CFI_is_contiguous (a))
+ abort ();
+
+ if (abs (a->dim[0].sm) < a->elem_len)
+ abort ();
+
+ for (int j = 0; j < 5; ++j)
+ for (int i = 0; i < 10; ++i)
+ {
+ subscripts[0] = j; subscripts[1] = i;
+ if (*(int *) CFI_address (a, subscripts) != (i+1) + 100*(j+1))
+ abort ();
+ }
+}
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-7.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-7.f90
@@ -0,0 +1,147 @@
+! PR 101309
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-7-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests passing arrays that may not be contiguous through
+! descriptors to C functions as assumed-shape arguments.
+
+program testit
+ use iso_c_binding
+ implicit none (type, external)
+
+ interface
+ subroutine ctest (a, is_cont) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(:,:)
+ logical(C_Bool), value :: is_cont
+ end subroutine
+ subroutine ctest_cont (a, is_cont) bind (c, name="ctest")
+ use iso_c_binding
+ integer(C_INT), contiguous :: a(:,:)
+ logical(C_Bool), value :: is_cont
+ end subroutine
+
+ subroutine ctest_ar (a, is_cont) bind (c, name="ctest")
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ logical(C_Bool), value :: is_cont
+ end subroutine
+ subroutine ctest_ar_cont (a, is_cont) bind (c, name="ctest")
+ use iso_c_binding
+ integer(C_INT), contiguous :: a(..)
+ logical(C_Bool), value :: is_cont
+ end subroutine
+ end interface
+
+ integer :: i , j
+ integer(C_INT), target :: aa(10,5)
+ integer(C_INT), target :: bb(10,10)
+
+ ! Original array
+ do j = 1, 5
+ do i = 1, 10
+ aa(i,j) = i + 100*j
+ end do
+ end do
+
+ ! Transposed array
+ do j = 2, 10, 2
+ do i = 1, 10
+ bb(j, i) = i + 100*((j-2)/2 + 1)
+ end do
+ end do
+
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+
+ ! Test both calling the C function directly, and via another function
+ ! that takes an assumed-shape/assumed-rank argument.
+
+ call ftest (transpose (aa), is_cont=.true._c_bool) ! Implementation choice: copy in; hence, contiguous
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+
+ call ctest (transpose (aa), is_cont=.false._c_bool) ! Implementation choice: noncontigous / sm inversed
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+ call ctest_cont (transpose (aa), is_cont=.true._c_bool)
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+ call ctest_ar (transpose (aa), is_cont=.false._c_bool) ! Implementation choice: noncontigous / sm inversed
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+ call ctest_ar_cont (transpose (aa), is_cont=.true._c_bool)
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+
+
+ call ftest (bb(2:10:2, :), is_cont=.false._c_bool)
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+
+ call ctest (bb(2:10:2, :), is_cont=.false._c_bool)
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+ call ctest_cont (bb(2:10:2, :), is_cont=.true._c_bool)
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+ call ctest_ar (bb(2:10:2, :), is_cont=.false._c_bool)
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+ call ctest_ar_cont (bb(2:10:2, :), is_cont=.true._c_bool)
+ if (any (transpose (aa) /= bb(2:10:2, :))) error stop 1
+
+contains
+ subroutine ftest (a, is_cont)
+ use iso_c_binding
+ integer(C_INT) :: a(:,:)
+ logical(c_bool), value, intent(in) :: is_cont
+ if (is_cont .NEQV. is_contiguous (a)) error stop 2
+ if (any (shape (a) /= [5, 10])) error stop 3
+ do j = 1, 5
+ do i = 1, 10
+ if (a(j, i) /= i + 100*j) error stop 4
+ if (a(j, i) /= aa(i,j)) error stop
+ end do
+ end do
+ call ctest (a, is_cont)
+ call ctest_cont (a, is_cont=.true._c_bool)
+ call ctest_ar (a, is_cont)
+ call ctest_ar_cont (a, is_cont=.true._c_bool)
+ end subroutine
+
+ subroutine ftest_ar (a, is_cont)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ logical(c_bool), value, intent(in) :: is_cont
+ if (is_cont .NEQV. is_contiguous (a)) error stop 2
+ if (any (shape (a) /= [5, 10])) error stop 3
+ select rank (a)
+ rank(2)
+ do j = 1, 5
+ do i = 1, 10
+ if (a(j, i) /= i + 100*j) error stop 4
+ if (a(j, i) /= aa(i,j)) error stop
+ end do
+ end do
+ call ctest (a, is_cont)
+ call ctest_cont (a, is_cont=.true._c_bool)
+ call ftest_ar_con (a, is_cont=.true._c_bool)
+ end select
+ call ctest_ar (a, is_cont)
+ ! call ctest_ar_cont (a, is_cont=.true._c_bool) ! TODO/FIXME: ICE, cf. PR fortran/102729
+ ! call ftest_ar_con (a, is_cont=.true._c_bool) ! TODO/FIXME: ICE, cf. PR fortran/102729
+ end subroutine
+
+ subroutine ftest_ar_con (a, is_cont)
+ use iso_c_binding
+ integer(C_INT), contiguous :: a(..)
+ logical(c_bool), value, intent(in) :: is_cont
+ if (is_cont .NEQV. is_contiguous (a)) error stop 2
+ if (any (shape (a) /= [5, 10])) error stop 3
+ select rank (a)
+ rank(2)
+ do j = 1, 5
+ do i = 1, 10
+ if (a(j, i) /= i + 100*j) error stop 4
+ if (a(j, i) /= aa(i,j)) error stop
+ end do
+ end do
+ call ctest (a, is_cont)
+ call ctest_cont (a, is_cont=.true._c_bool)
+ end select
+ call ctest_ar (a, is_cont)
+ call ctest_ar_cont (a, is_cont=.true._c_bool)
+ end subroutine
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-8-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-8-c.c
@@ -0,0 +1,20 @@
+/* TS29113 8.3.1: ISO_Fortran_binding.h may be included more than once. */
+
+#include
+
+#include
+#include "dump-descriptors.h"
+#include
+
+extern void ctest (CFI_cdesc_t *a);
+
+void
+ctest (CFI_cdesc_t *a)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->version != CFI_VERSION)
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-8.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-8.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-8-c.c dump-descriptors.c" }
+!
+! Check that C descriptors have the version field set correctly.
+! This program is just a stub to create a descriptor and pass it to the
+! C function, which does the actual test.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(:,:)
+ end subroutine
+ end interface
+
+ integer(C_INT) :: aa(10,-1:3)
+ call ctest (aa)
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-9-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-9-c.c
@@ -0,0 +1,42 @@
+/* 8.3.1: ISO_Fortran_binding.h may be included more than once. */
+
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+
+struct descriptor_fixed_part {
+ void *base_addr;
+ size_t elem_len;
+ int version;
+};
+
+void
+ctest (CFI_cdesc_t *a)
+{
+ struct descriptor_fixed_part *f = (struct descriptor_fixed_part *) a;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* The first three members of the structure shall be base_addr,
+ elem_len, and version in that order. */
+ if (&(a->base_addr) != &(f->base_addr))
+ abort ();
+ if (&(a->elem_len) != &(f->elem_len))
+ abort ();
+ if (&(a->version) != &(f->version))
+ abort ();
+
+ /* The final member shall be dim, with the other members after version
+ and before dim in any order. */
+ if ((void *)&(a->rank) >= (void *)a->dim)
+ abort ();
+ if ((void *)&(a->type) >= (void *)a->dim)
+ abort ();
+ if ((void *)&(a->attribute) >= (void *)a->dim)
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-9.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-9.f90
@@ -0,0 +1,23 @@
+! { dg-do run }
+! { dg-additional-sources "fc-descriptor-9-c.c dump-descriptors.c" }
+!
+! Check that C descriptors follow the layout restrictions described in
+! section 8.3.3 of TS29113.
+! This program is just a stub to create a descriptor and pass it to the
+! C function, which does the actual test.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(:,:)
+ end subroutine
+ end interface
+
+ integer(C_INT) :: aa(10,-1:3)
+ call ctest (aa)
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-descriptor-pr108621.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-descriptor-pr108621.f90
@@ -0,0 +1,65 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/108621
+!
+! If the bind(C) procedure's dummy argument is a POINTER with INTENT(OUT),
+! avoid converting the array bounds for the CFI descriptor before the call.
+!
+! Rational: Fewer code and, esp. for undefined pointers, there might be a
+! compile-time warning or a runtime error due to the 'extent' arithmentic
+! and integer overflows (i.e. random values and -fsanitize=undefined).
+!
+! (For disassociated pointers, it would/should be only pointless code as
+! the bound setting is guarded by a != NULL condtion. However, as the PR shows,
+! a bogus may-use-uninitialized-memory warning might still be shown in that case.)
+!
+! Without 'intent' (but still intent(out) internally), the same applies but
+! there is nothing the compiler can do on the caller side.
+! Still, as only uninit memory and not invalid memory it accessed, it should still
+! work (at least when run-time checking is turned off).
+!
+subroutine demo(f)
+use, intrinsic :: iso_c_binding, only : c_int
+implicit none
+
+interface
+ subroutine fun(f_p) bind(c)
+ import c_int
+ integer(c_int), pointer, intent(out) :: f_p(:)
+ end subroutine
+end interface
+
+integer(c_int), pointer :: f(:)
+
+call fun(f)
+end
+
+! The following ones must be present even with intent(out):
+!
+! { dg-final { scan-tree-dump "cfi...version = 1;" "original" } }
+! { dg-final { scan-tree-dump "cfi...rank = 1;" "original" } }
+! { dg-final { scan-tree-dump "cfi...type = 1025;" "original" } }
+! { dg-final { scan-tree-dump "cfi...attribute = 0;" "original" } }
+! { dg-final { scan-tree-dump "cfi...elem_len = 4;" "original" } }
+
+
+! The following is not needed - but user code might expect that an incoming pointer is NULL
+! in this case. - At least the GCC testsuite expects this in the C code at
+! gfortran.dg/c-interop/section-{1,2}.f90
+! Thus, it is kept as it does not cause any harm:
+!
+! { dg-final { scan-tree-dump "cfi...base_addr = f->data;" "original" } }
+
+
+! The following ones are not need with intent(out) and, therefore, shouldn't be there:
+!
+! cfi.0.dim[idx.1].lower_bound = f->dim[idx.1].lbound;
+! cfi.0.dim[idx.1].extent = (f->dim[idx.1].ubound - f->dim[idx.1].lbound) + 1;
+! cfi.0.dim[idx.1].sm = f->dim[idx.1].stride * f->span;
+!
+! Now match those - but using a rather generic pattern as it is a ...-not scan:
+!
+! { dg-final { scan-tree-dump-not "lower_bound = " "original" } }
+! { dg-final { scan-tree-dump-not "extent = " "original" } }
+! { dg-final { scan-tree-dump-not "sm = " "original" } }
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-1-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-1-c.c
@@ -0,0 +1,52 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (int imax, int jmax, CFI_cdesc_t *a);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest (int imax, int jmax, CFI_cdesc_t *a)
+{
+
+ int i, j;
+ CFI_index_t subscripts[2];
+ struct m* mp;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != imax)
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != jmax)
+ abort ();
+
+ /* Fill in the contents of a. a is zero-based but we want the ->i and ->j
+ members of each element to be numbered starting from 1. */
+ for (j = 0; j < jmax; j++)
+ {
+ subscripts[1] = j;
+ for (i = 0; i < imax; i++)
+ {
+ subscripts[0] = i;
+ mp = (struct m *) CFI_address (a, subscripts);
+ mp->i = i + 1;
+ mp->j = j + 1;
+ }
+ }
+}
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-1.f90
@@ -0,0 +1,66 @@
+! { dg-do run }
+! { dg-additional-sources "fc-out-descriptor-1-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that passing a fixed-size array as an intent(out)
+! assumed-shape argument to a C function called from Fortran works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (ii, jj, a) bind (c)
+ use iso_c_binding
+ use mm
+ integer(C_INT), value :: ii, jj
+ type(m), intent(out) :: a(:,:)
+ end subroutine
+ end interface
+
+ type(m) :: aa(imax,jmax)
+ integer :: i, j
+
+ ! initialize the array to all zeros; ctest will overwrite it.
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = 0
+ aa(i,j)%j = 0
+ end do
+ end do
+
+ call ctest (imax, jmax, aa)
+ call verify (aa)
+
+contains
+subroutine verify (a)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ integer :: i, j
+
+ if (rank (a) .ne. 2) stop 100
+ if (lbound (a, 1) .ne. 1) stop 101
+ if (lbound (a, 2) .ne. 1) stop 102
+ if (ubound (a, 1) .ne. imax) stop 103
+ if (ubound (a, 2) .ne. jmax) stop 104
+
+ do j = 1, jmax
+ do i = 1, imax
+ if (a(i,j)%i .ne. i) stop 201
+ if (a(i,j)%j .ne. j) stop 202
+ end do
+ end do
+end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-2-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-2-c.c
@@ -0,0 +1,52 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (int imax, int jmax, CFI_cdesc_t *a);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest (int imax, int jmax, CFI_cdesc_t *a)
+{
+
+ int i, j;
+ CFI_index_t subscripts[2];
+ struct m* mp;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != imax)
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != jmax)
+ abort ();
+
+ /* Fill in the contents of a. a is zero-based but we want the ->i and ->j
+ members of each element to be numbered starting from 1. */
+ for (j = 0; j < jmax; j++)
+ {
+ subscripts[1] = j;
+ for (i = 0; i < imax; i++)
+ {
+ subscripts[0] = i;
+ mp = (struct m *) CFI_address (a, subscripts);
+ mp->i = i + 1;
+ mp->j = j + 1;
+ }
+ }
+}
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-2.f90
@@ -0,0 +1,66 @@
+! { dg-do run }
+! { dg-additional-sources "fc-out-descriptor-2-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that passing a fixed-size array as an intent(out)
+! assumed-rank argument to a C function called from Fortran works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (ii, jj, a) bind (c)
+ use iso_c_binding
+ use mm
+ integer(C_INT), value :: ii, jj
+ type(m), intent(out) :: a(..)
+ end subroutine
+ end interface
+
+ type(m) :: aa(imax,jmax)
+ integer :: i, j
+
+ ! initialize the array to all zeros; ctest will overwrite it.
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = 0
+ aa(i,j)%j = 0
+ end do
+ end do
+
+ call ctest (imax, jmax, aa)
+ call verify (aa)
+
+contains
+subroutine verify (a)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ integer :: i, j
+
+ if (rank (a) .ne. 2) stop 100
+ if (lbound (a, 1) .ne. 1) stop 101
+ if (lbound (a, 2) .ne. 1) stop 102
+ if (ubound (a, 1) .ne. imax) stop 103
+ if (ubound (a, 2) .ne. jmax) stop 104
+
+ do j = 1, jmax
+ do i = 1, imax
+ if (a(i,j)%i .ne. i) stop 201
+ if (a(i,j)%j .ne. j) stop 202
+ end do
+ end do
+end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-3-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-3-c.c
@@ -0,0 +1,71 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest1 (int iinit, int jinit, CFI_cdesc_t *p);
+extern void ctest2 (int iinit, int jinit, CFI_cdesc_t *a);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest1 (int iinit, int jinit, CFI_cdesc_t *p)
+{
+ struct m *mp;
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (p);
+
+ if (p->rank != 0)
+ abort ();
+ if (p->attribute != CFI_attribute_pointer)
+ abort ();
+ if (p->type != CFI_type_struct)
+ abort ();
+
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (p, NULL, NULL, sizeof (struct m)));
+
+ if (p->base_addr == NULL)
+ abort ();
+
+ mp = (struct m *) CFI_address (p, NULL);
+ mp->i = iinit;
+ mp->j = jinit;
+}
+
+
+void
+ctest2 (int iinit, int jinit, CFI_cdesc_t *a)
+{
+ struct m *mp;
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 0)
+ abort ();
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (a->type != CFI_type_struct)
+ abort ();
+
+ /* The intent(out) allocatable array is supposed to be deallocated
+ automatically on entry, if it was previously allocated. */
+ if (a->base_addr)
+ abort ();
+
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (a, NULL, NULL, sizeof (struct m)));
+
+ if (a->base_addr == NULL)
+ abort ();
+
+ mp = (struct m *) CFI_address (a, NULL);
+ mp->i = iinit;
+ mp->j = jinit;
+}
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-3.f90
@@ -0,0 +1,59 @@
+! PR 101308
+! { dg-do run }
+! { dg-additional-sources "fc-out-descriptor-3-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that passing an allocatable or pointer scalar
+! as an intent(out) argument to a C function called from Fortran works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer(C_INT), parameter :: iinit = 42, jinit = 12345
+
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest1 (ii, jj, p) bind (c)
+ use iso_c_binding
+ use mm
+ integer(C_INT), value :: ii, jj
+ type(m), intent(out), pointer :: p
+ end subroutine
+ subroutine ctest2 (ii, jj, a) bind (c)
+ use iso_c_binding
+ use mm
+ integer(C_INT), value :: ii, jj
+ type(m), intent(out), allocatable :: a
+ end subroutine
+ end interface
+
+ type(m), pointer :: p
+ type(m), allocatable :: a
+
+ ! The association status of the intent(out) pointer argument is supposed
+ ! to become undefined on entry to the called procedure.
+ p => NULL ()
+ call ctest1 (iinit, jinit, p)
+ if (.not. associated (p)) stop 101
+ if (p%i .ne. iinit) stop 102
+ if (p%j .ne. jinit) stop 103
+
+ ! The intent(out) argument is supposed to be deallocated automatically
+ ! on entry to the called function.
+ allocate (a)
+ a%i = 0
+ a%j = 0
+ call ctest2 (iinit, jinit, a)
+ if (.not. allocated (a)) stop 201
+ if (a%i .ne. iinit) stop 202
+ if (a%j .ne. jinit) stop 203
+end program
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-4-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-4-c.c
@@ -0,0 +1,96 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest1 (int imin, int imax, int jmin, int jmax, CFI_cdesc_t *p);
+extern void ctest2 (int imin, int imax, int jmin, int jmax, CFI_cdesc_t *a);
+
+struct m {
+ int i;
+ int j;
+};
+
+void
+ctest1 (int imin, int imax, int jmin, int jmax, CFI_cdesc_t *p)
+{
+ struct m *mp;
+ int i, j;
+ CFI_index_t lb[2], ub[2], s[2];
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (p);
+
+ if (p->rank != 2)
+ abort ();
+ if (p->attribute != CFI_attribute_pointer)
+ abort ();
+ if (p->type != CFI_type_struct)
+ abort ();
+
+ lb[0] = imin;
+ lb[1] = jmin;
+ ub[0] = imax;
+ ub[1] = jmax;
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (p, lb, ub, sizeof (struct m)));
+
+ if (p->base_addr == NULL)
+ abort ();
+
+ for (j = jmin; j <= jmax; j++)
+ for (i = imin; i <= imax; i++)
+ {
+ s[0] = i;
+ s[1] = j;
+ mp = (struct m *) CFI_address (p, s);
+ mp->i = i;
+ mp->j = j;
+ }
+}
+
+void
+ctest2 (int imin, int imax, int jmin, int jmax, CFI_cdesc_t *a)
+{
+ struct m *mp;
+ int i, j;
+ CFI_index_t lb[2], ub[2], s[2];
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_allocatable)
+ abort ();
+ if (a->type != CFI_type_struct)
+ abort ();
+
+ /* Intent(out) argument is supposed to be deallocated automatically
+ on entry. */
+ if (a->base_addr)
+ abort ();
+
+ lb[0] = imin;
+ lb[1] = jmin;
+ ub[0] = imax;
+ ub[1] = jmax;
+ check_CFI_status ("CFI_allocate",
+ CFI_allocate (a, lb, ub, sizeof (struct m)));
+
+ if (a->base_addr == NULL)
+ abort ();
+
+ for (j = jmin; j <= jmax; j++)
+ for (i = imin; i <= imax; i++)
+ {
+ s[0] = i;
+ s[1] = j;
+ mp = (struct m *) CFI_address (a, s);
+ mp->i = i;
+ mp->j = j;
+ }
+}
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-4.f90
@@ -0,0 +1,75 @@
+! PR 92621 (?)
+! { dg-do run }
+! { dg-additional-sources "fc-out-descriptor-4-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that passing an allocatable or pointer array
+! as an intent(out) argument to a C function called from Fortran works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer(C_INT), parameter :: imin = 5, imax = 10, jmin = -10, jmax = -1
+
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest1 (i0, ii, j0, jj, p) bind (c)
+ use iso_c_binding
+ use mm
+ integer(C_INT), value :: i0, ii, j0, jj
+ type(m), intent(out), pointer :: p(:,:)
+ end subroutine
+ subroutine ctest2 (i0, ii, j0, jj, a) bind (c)
+ use iso_c_binding
+ use mm
+ integer(C_INT), value :: i0, ii, j0, jj
+ type(m), intent(out), allocatable :: a(:,:)
+ end subroutine
+ end interface
+
+ type(m), pointer :: p(:,:)
+ type(m), allocatable :: a(:,:)
+ integer :: i, j
+
+ p => NULL ()
+ call ctest1 (imin, imax, jmin, jmax, p)
+ if (.not. associated (p)) stop 101
+ if (rank(p) .ne. 2) stop 102
+ if (lbound (p, 1) .ne. imin) stop 103
+ if (ubound (p, 1) .ne. imax) stop 104
+ if (lbound (p, 2) .ne. jmin) stop 105
+ if (ubound (p, 2) .ne. jmax) stop 106
+ do j = jmin, jmax
+ do i = imin, imax
+ if (p(i,j)%i .ne. i) stop 107
+ if (p(i,j)%j .ne. j) stop 108
+ end do
+ end do
+
+ ! The intent(out) argument is supposed to be deallocated automatically
+ ! on entry to the called function.
+ allocate (a (jmin:jmax,imin:imax))
+ if (.not. allocated (a)) stop 201
+ call ctest2 (imin, imax, jmin, jmax, a)
+ if (.not. allocated (a)) stop 201
+ if (rank(a) .ne. 2) stop 202
+ if (lbound (a, 1) .ne. imin) stop 203
+ if (ubound (a, 1) .ne. imax) stop 204
+ if (lbound (a, 2) .ne. jmin) stop 205
+ if (ubound (a, 2) .ne. jmax) stop 206
+ do j = jmin, jmax
+ do i = imin, imax
+ if (a(i,j)%i .ne. i) stop 207
+ if (a(i,j)%j .ne. j) stop 208
+ end do
+ end do
+end program
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-5-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-5-c.c
@@ -0,0 +1,30 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+
+void
+ctest (CFI_cdesc_t *a)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* The character object passed as the argument was declared on the
+ Fortran side as character(len=26) :: aa
+ Make sure that matches what's in the descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != 26)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (a->type != CFI_type_char)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ strncpy ((char *)a->base_addr, "0123456789", 10);
+}
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-5.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-5.f90
@@ -0,0 +1,35 @@
+! PR92482
+! { dg-do run }
+! { dg-additional-sources "fc-out-descriptor-5-c.c dump-descriptors.c" }
+!
+! This program checks that you can call a C function declared with an
+! assumed-length character dummy from Fortran.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ character(len=*,kind=C_CHAR), intent(out) :: a
+ end subroutine
+ end interface
+
+ character(len=26,kind=C_CHAR) :: aa
+ aa = 'abcdefghijklmnopqrstuvwxyz'
+
+ ! Test both passing the fixed-length-string directly to the function
+ ! with a C interface, and indirectly via a Fortran function with an
+ ! assumed-length dummy argument.
+ call ctest (aa)
+ call ftest (aa)
+
+contains
+ subroutine ftest (a) bind (c)
+ use iso_c_binding
+ character(len=*,kind=C_CHAR), intent(out) :: a
+ call ctest (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-6-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-6-c.c
@@ -0,0 +1,50 @@
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a);
+
+void
+ctest (CFI_cdesc_t *a)
+{
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ dump_CFI_cdesc_t (a);
+
+ /* The actual argument on the Fortran side was declared as
+ integer(C_INT) :: aa(10,5:8)
+ but was passed via other functions that variously describe it as
+ having size (10,*), (10,1:*), or (10,5:*) before calling this function
+ with an assumed-rank array dummy. But, the spec says:
+
+ For a C descriptor of a nonallocatable nonpointer object, the
+ value of the lower_bound member of each element of the dim member
+ of the descriptor is zero.
+
+ In a C descriptor of an assumed-size array, the extent member of
+ the last element of the dim member has the value −1. */
+
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 2)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != 10)
+ abort ();
+ if (a->dim[0].sm != sizeof(int))
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != -1)
+ abort ();
+ if (a->dim[1].sm != a->dim[0].extent * sizeof(int))
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-6.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-6.f90
@@ -0,0 +1,49 @@
+! Reported as pr94070.
+! { dg-do run }
+! { dg-additional-sources "fc-out-descriptor-6-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks passing an assumed-size array argument via descriptor
+! from Fortran to C.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ ! Assumed-size arrays are not passed by descriptor. What we'll do
+ ! for this test function is bind an assumed-rank dummy to an
+ ! assumed-size array. This is supposed to fill in the descriptor
+ ! with information about the array present at the call site.
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ integer(C_INT), intent(out) :: a(..)
+ end subroutine
+ end interface
+
+ integer(C_INT), target :: aa(10,5:8)
+
+ ! To get an assumed-size array descriptor, we have to first pass the
+ ! fixed-size array to a Fortran function with an assumed-size dummy.
+ call ftest1 (aa)
+ call ftest2 (aa)
+ call ftest3 (aa)
+
+contains
+ subroutine ftest1 (a)
+ use iso_c_binding
+ integer(C_INT) :: a(10,*)
+ call ctest (a)
+ end subroutine
+ subroutine ftest2 (a)
+ use iso_c_binding
+ integer(C_INT) :: a(10,5:*)
+ call ctest (a)
+ end subroutine
+ subroutine ftest3 (a)
+ use iso_c_binding
+ integer(C_INT) :: a(10,1:*)
+ call ctest (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-7-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-7-c.c
@@ -0,0 +1,136 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+struct m {
+ int i;
+ int j;
+};
+
+extern void ctest (CFI_cdesc_t *a, int lb1, int ub1, int s1,
+ int lb2, int ub2, int s2, CFI_cdesc_t *b);
+
+/* Check array b against the section of array a defined by the given
+ bounds. */
+static void
+check_array (CFI_cdesc_t *a, CFI_cdesc_t *b,
+ int lb1, int ub1, int s1, int lb2, int ub2, int s2)
+{
+ int bad = 0;
+ int i, ii, j, jj;
+ CFI_index_t sub[2];
+ struct m *ap, *bp;
+
+ for (j = lb2, jj = b->dim[1].lower_bound; j <= ub2; jj++, j += s2)
+ for (i = lb1, ii = b->dim[0].lower_bound; i <= ub1; ii++, i += s1)
+ {
+ sub[0] = i;
+ sub[1] = j;
+ ap = (struct m *) CFI_address (a, sub);
+ sub[0] = ii;
+ sub[1] = jj;
+ bp = (struct m *) CFI_address (b, sub);
+#if 0
+ fprintf (stderr, "b(%d,%d) = (%d,%d) expecting (%d,%d)\n",
+ ii, jj, bp->i, bp->j, ap->i, ap->j);
+#endif
+ if (ap->i != bp->i || ap->j != bp->j)
+ bad = 1;
+ }
+ if (bad)
+ abort ();
+}
+
+void
+ctest (CFI_cdesc_t *a, int lb1, int ub1, int s1,
+ int lb2, int ub2, int s2, CFI_cdesc_t *b)
+{
+ CFI_index_t lb[2], ub[2], s[2];
+ CFI_index_t i, j;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ fprintf (stderr, "input arrays\n");
+ dump_CFI_cdesc_t (a);
+ dump_CFI_cdesc_t (b);
+
+ /* We expect to get a zero-based input array of shape (10,5). */
+ if (a->rank != 2)
+ abort ();
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->type != CFI_type_struct)
+ abort ();
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ if (a->dim[0].extent != 10)
+ abort ();
+ if (a->dim[1].lower_bound != 0)
+ abort ();
+ if (a->dim[1].extent != 5)
+ abort ();
+
+ /* The output descriptor has to agree with the input descriptor. */
+ if (b->rank != 2)
+ abort ();
+ if (b->attribute != CFI_attribute_pointer)
+ abort ();
+ if (b->type != CFI_type_struct)
+ abort ();
+ if (b->elem_len != a->elem_len)
+ abort ();
+
+ /* Point b at a, keeping the 0-based bounds. */
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (b, a, NULL));
+ fprintf (stderr, "After initializing b\n");
+ dump_CFI_cdesc_t (b);
+ if (b->dim[0].lower_bound != 0)
+ abort ();
+ if (b->dim[1].lower_bound != 0)
+ abort ();
+ check_array (a, b,
+ a->dim[0].lower_bound,
+ a->dim[0].lower_bound + a->dim[0].extent - 1,
+ 1,
+ a->dim[1].lower_bound,
+ a->dim[1].lower_bound + a->dim[1].extent - 1,
+ 1);
+
+ /* Take a section of the array. The bounds passed in to this function
+ assume the array is 1-based in both dimensions, so subtract 1. */
+ lb[0] = b->dim[0].lower_bound + lb1 - 1;
+ lb[1] = b->dim[1].lower_bound + lb2 - 1;
+ ub[0] = b->dim[0].lower_bound + ub1 - 1;
+ ub[1] = b->dim[1].lower_bound + ub2 - 1;
+ s[0] = s1;
+ s[1] = s2;
+ check_CFI_status ("CFI_section",
+ CFI_section (b, b, lb, ub, s));
+ fprintf (stderr, "After CFI_section\n");
+ dump_CFI_cdesc_t (b);
+ check_array (a, b,
+ a->dim[0].lower_bound + lb1 - 1,
+ a->dim[0].lower_bound + ub1 - 1,
+ s1,
+ a->dim[1].lower_bound + lb2 - 1,
+ a->dim[1].lower_bound + ub2 - 1,
+ s2);
+
+ /* Adjust b to be 1-based. */
+ lb[0] = 1;
+ lb[1] = 1;
+ fprintf (stderr, "After rebasing b again\n");
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (b, b, lb));
+ dump_CFI_cdesc_t (b);
+ check_array (a, b,
+ a->dim[0].lower_bound + lb1 - 1,
+ a->dim[0].lower_bound + ub1 - 1,
+ s1,
+ a->dim[1].lower_bound + lb2 - 1,
+ a->dim[1].lower_bound + ub2 - 1,
+ s2);
+}
Index: Fortran/gfortran/regression/c-interop/fc-out-descriptor-7.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/fc-out-descriptor-7.f90
@@ -0,0 +1,71 @@
+! PR 101310
+! { dg-do run }
+! { dg-additional-sources "fc-out-descriptor-7-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program checks that returning a noncontiguous array as an intent(out)
+! argument to a C function called from Fortran works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer(C_INT), parameter :: imax = 10, jmax=5
+
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ ! ctest points b at a section of array a defined by the
+ ! indicated bounds and steps. The returned array is 1-based.
+ subroutine ctest (a, lb1, ub1, s1, lb2, ub2, s2, b) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), target :: a(:,:)
+ integer(C_INT), value :: lb1, ub1, s1, lb2, ub2, s2
+ type(m), intent(out), pointer :: b(:,:)
+ end subroutine
+ end interface
+
+ type(m), target :: a(imax, jmax)
+ type(m), pointer :: b(:,:)
+ integer :: i, j, ii, jj
+
+ do j = 1, jmax
+ do i = 1, imax
+ a(i,j)%i = i
+ a(i,j)%j = j
+ end do
+ end do
+
+ b => NULL ()
+ ! resulting array is 1-based and has shape (3,3)
+ call ctest (a, 2, 8, 3, 1, 5, 2, b)
+ if (.not. associated (b)) stop 101
+ if (rank(b) .ne. 2) stop 102
+ if (lbound (b, 1) .ne. 1) stop 103
+ if (ubound (b, 1) .ne. 3) stop 104
+ if (lbound (b, 2) .ne. 1) stop 105
+ if (ubound (b, 2) .ne. 3) stop 106
+
+ ! check that the returned array b contains the expected elements
+ ! from array a.
+ jj = lbound (b, 2)
+ do j = 1, 5, 2
+ ii = lbound (b, 1)
+ do i = 2, 8, 3
+ if (b(ii,jj)%i .ne. i) stop 107
+ if (b(ii,jj)%j .ne. j) stop 108
+ ii = ii + 1
+ end do
+ jj = jj + 1
+ end do
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/ff-descriptor-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ff-descriptor-1.f90
@@ -0,0 +1,123 @@
+! { dg-do run }
+!
+! This program checks that passing arrays as assumed-shape dummies to
+! and from Fortran functions with C binding works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ type(m) :: aa(imax,jmax)
+ integer :: i, j
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ end do
+ end do
+
+ call testc (aa)
+ call testf (aa)
+
+contains
+
+ ! C binding version
+
+ subroutine checkc (a, b) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:), b(:,:)
+ integer :: i, j
+
+ if (size (a,1) .ne. imax) stop 101
+ if (size (a,2) .ne. jmax) stop 102
+ if (size (b,1) .ne. jmax) stop 103
+ if (size (b,2) .ne. imax) stop 104
+
+ do j = 1, jmax
+ do i = 1, imax
+ if (a(i,j)%i .ne. i) stop 105
+ if (a(i,j)%j .ne. j) stop 106
+ if (b(j,i)%i .ne. i) stop 107
+ if (b(j,i)%j .ne. j) stop 108
+ end do
+ end do
+ end subroutine
+
+ ! Fortran binding version
+ subroutine checkf (a, b)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:), b(:,:)
+ integer :: i, j
+
+ if (size (a,1) .ne. imax) stop 201
+ if (size (a,2) .ne. jmax) stop 202
+ if (size (b,1) .ne. jmax) stop 203
+ if (size (b,2) .ne. imax) stop 204
+
+ do j = 1, jmax
+ do i = 1, imax
+ if (a(i,j)%i .ne. i) stop 205
+ if (a(i,j)%j .ne. j) stop 206
+ if (b(j,i)%i .ne. i) stop 207
+ if (b(j,i)%j .ne. j) stop 208
+ end do
+ end do
+ end subroutine
+
+ ! C binding version
+ subroutine testc (a) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m) :: b(jmax, imax)
+ integer :: i, j
+
+ if (size (a,1) .ne. imax) stop 301
+ if (size (a,2) .ne. jmax) stop 302
+ do j = 1, jmax
+ do i = 1, imax
+ b(j,i)%i = a(i,j)%i
+ b(j,i)%j = a(i,j)%j
+ end do
+ end do
+
+ ! Call both the C and Fortran binding check functions
+ call checkc (a, b)
+ call checkf (a, b)
+ end subroutine
+
+ ! Fortran binding version
+ subroutine testf (a)
+ use iso_c_binding
+ use mm
+ type(m) :: a(:,:)
+ type(m) :: b(jmax, imax)
+ integer :: i, j
+
+ if (size (a,1) .ne. imax) stop 401
+ if (size (a,2) .ne. jmax) stop 402
+ do j = 1, jmax
+ do i = 1, imax
+ b(j,i)%i = a(i,j)%i
+ b(j,i)%j = a(i,j)%j
+ end do
+ end do
+
+ ! Call both the C and Fortran binding check functions
+ call checkc (a, b)
+ call checkf (a, b)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/ff-descriptor-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ff-descriptor-2.f90
@@ -0,0 +1,97 @@
+! { dg-do run }
+!
+! This program checks that passing arrays as assumed-rank dummies to
+! and from Fortran functions with C binding works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imax=10, jmax=5
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ type(m) :: aa(imax,jmax)
+ integer :: i, j
+ do j = 1, jmax
+ do i = 1, imax
+ aa(i,j)%i = i
+ aa(i,j)%j = j
+ end do
+ end do
+
+ call testc (aa)
+ call testf (aa)
+
+contains
+
+ ! C binding version
+
+ subroutine checkc (a, b) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(..), b(..)
+
+ if (rank (a) .ne. 2) stop 101
+ if (rank (b) .ne. 2) stop 102
+ if (size (a,1) .ne. imax) stop 103
+ if (size (a,2) .ne. jmax) stop 104
+ if (size (b,1) .ne. jmax) stop 105
+ if (size (b,2) .ne. imax) stop 106
+
+ end subroutine
+
+ ! Fortran binding version
+ subroutine checkf (a, b)
+ use iso_c_binding
+ use mm
+ type(m) :: a(..), b(..)
+
+ if (rank (a) .ne. 2) stop 201
+ if (rank (b) .ne. 2) stop 202
+ if (size (a,1) .ne. imax) stop 203
+ if (size (a,2) .ne. jmax) stop 204
+ if (size (b,1) .ne. jmax) stop 205
+ if (size (b,2) .ne. imax) stop 206
+
+ end subroutine
+
+ ! C binding version
+ subroutine testc (a) bind (c)
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ type(m) :: b(jmax, imax)
+
+ if (rank (a) .ne. 2) stop 301
+ if (size (a,1) .ne. imax) stop 302
+ if (size (a,2) .ne. jmax) stop 303
+
+ ! Call both the C and Fortran binding check functions
+ call checkc (a, b)
+ call checkf (a, b)
+ end subroutine
+
+ ! Fortran binding version
+ subroutine testf (a)
+ use iso_c_binding
+ use mm
+ type(m) :: a(..)
+ type(m) :: b(jmax, imax)
+
+ if (rank (a) .ne. 2) stop 401
+ if (size (a,1) .ne. imax) stop 402
+ if (size (a,2) .ne. jmax) stop 403
+
+ ! Call both the C and Fortran binding check functions
+ call checkc (a, b)
+ call checkf (a, b)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/ff-descriptor-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ff-descriptor-3.f90
@@ -0,0 +1,148 @@
+! { dg-do run }
+!
+! This program checks that passing allocatable and pointer scalars to
+! and from Fortran functions with C binding works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+
+ integer, parameter :: imagic=-1, jmagic=42
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ type(m), allocatable :: a
+ type(m), target :: t
+ type(m), pointer :: p
+
+ p => NULL()
+
+ call testc (a, t, p)
+ call testf (a, t, p)
+
+contains
+
+ ! C binding version
+
+ subroutine checkc (a, t, p, initp) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a
+ type(m), target :: t
+ type(m), pointer :: p
+ logical, value :: initp
+
+ if (initp) then
+ if (.not. allocated (a)) stop 101
+ if (a%i .ne. imagic) stop 102
+ if (a%j .ne. jmagic) stop 103
+ if (.not. associated (p)) stop 104
+ if (.not. associated (p, t)) stop 105
+ if (p%i .ne. imagic) stop 106
+ if (p%j .ne. jmagic) stop 107
+ else
+ if (allocated (a)) stop 108
+ if (associated (p)) stop 109
+ end if
+
+ if (rank (a) .ne. 0) stop 110
+ if (rank (t) .ne. 0) stop 111
+ if (rank (p) .ne. 0) stop 112
+
+ end subroutine
+
+ ! Fortran binding version
+ subroutine checkf (a, t, p, initp)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a
+ type(m), target :: t
+ type(m), pointer :: p
+ logical, value :: initp
+
+ if (initp) then
+ if (.not. allocated (a)) stop 201
+ if (a%i .ne. imagic) stop 202
+ if (a%j .ne. jmagic) stop 203
+ if (.not. associated (p)) stop 204
+ if (.not. associated (p, t)) stop 205
+ if (p%i .ne. imagic) stop 206
+ if (p%j .ne. jmagic) stop 207
+ else
+ if (allocated (a)) stop 208
+ if (associated (p)) stop 209
+ end if
+
+ if (rank (a) .ne. 0) stop 210
+ if (rank (t) .ne. 0) stop 211
+ if (rank (p) .ne. 0) stop 212
+
+ end subroutine
+
+ ! C binding version
+ subroutine testc (a, t, p) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a
+ type(m), target :: t
+ type(m), pointer :: p
+
+ ! Call both the C and Fortran binding check functions
+ call checkc (a, t, p, .false.)
+ call checkf (a, t, p, .false.)
+
+ ! Allocate/associate and check again.
+ allocate (a)
+ a%i = imagic
+ a%j = jmagic
+ p => t
+ t%i = imagic
+ t%j = jmagic
+ call checkc (a, t, p, .true.)
+ call checkf (a, t, p, .true.)
+
+ ! Reset and check a third time.
+ deallocate (a)
+ p => NULL ()
+ call checkc (a, t, p, .false.)
+ call checkf (a, t, p, .false.)
+
+ end subroutine
+
+ ! Fortran binding version
+ subroutine testf (a, t, p)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a
+ type(m), target :: t
+ type(m), pointer :: p
+
+ ! Call both the C and Fortran binding check functions
+ call checkc (a, t, p, .false.)
+ call checkf (a, t, p, .false.)
+
+ ! Allocate/associate and check again.
+ allocate (a)
+ a%i = imagic
+ a%j = jmagic
+ p => t
+ t%i = imagic
+ t%j = jmagic
+ call checkc (a, t, p, .true.)
+ call checkf (a, t, p, .true.)
+
+ ! Reset and check a third time.
+ deallocate (a)
+ p => NULL ()
+ call checkc (a, t, p, .false.)
+ call checkf (a, t, p, .false.)
+
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/ff-descriptor-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ff-descriptor-4.f90
@@ -0,0 +1,198 @@
+! { dg-do run }
+!
+! This program checks that passing allocatable and pointer arrays to
+! and from Fortran functions with C binding works.
+
+module mm
+ use iso_c_binding
+ type, bind (c) :: m
+ integer(C_INT) :: i, j
+ end type
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ type(m), allocatable :: a(:)
+ type(m), target :: t(3,10)
+ type(m), pointer :: p(:,:)
+
+ p => NULL()
+
+ call testc (a, t, p)
+ call testf (a, t, p)
+
+contains
+
+ ! C binding version
+
+ subroutine checkc (a, t, p, initp) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a(:)
+ type(m), target :: t(3,10)
+ type(m), pointer :: p(:,:)
+ logical, value :: initp
+ integer :: i, j
+
+ if (rank (a) .ne. 1) stop 101
+ if (rank (t) .ne. 2) stop 102
+ if (rank (p) .ne. 2) stop 103
+
+ if (initp) then
+ if (.not. allocated (a)) stop 104
+ if (.not. associated (p)) stop 105
+ if (.not. associated (p, t)) stop 106
+ if (size (a, 1) .ne. 5) stop 107
+ if (size (p, 1) .ne. 3) stop 108
+ if (size (p, 2) .ne. 10) stop 109
+ else
+ if (allocated (a)) stop 121
+ if (associated (p)) stop 122
+ end if
+
+ end subroutine
+
+ ! Fortran binding version
+ subroutine checkf (a, t, p, initp)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a(:)
+ type(m), target :: t(3,10)
+ type(m), pointer :: p(:,:)
+ logical, value :: initp
+ integer :: i, j
+
+ if (rank (a) .ne. 1) stop 201
+ if (rank (t) .ne. 2) stop 202
+ if (rank (p) .ne. 2) stop 203
+
+ if (initp) then
+ if (.not. allocated (a)) stop 204
+ if (.not. associated (p)) stop 205
+ if (.not. associated (p, t)) stop 206
+ if (size (a, 1) .ne. 5) stop 207
+ if (size (p, 1) .ne. 3) stop 208
+ if (size (p, 2) .ne. 10) stop 209
+ else
+ if (allocated (a)) stop 221
+ if (associated (p)) stop 222
+ end if
+
+ end subroutine
+
+ ! C binding version
+ subroutine allocatec (a, t, p) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a(:)
+ type(m), target :: t(3,10)
+ type(m), pointer :: p(:,:)
+
+ allocate (a(10:20))
+ p => t
+ end subroutine
+
+ ! Fortran binding version
+ subroutine allocatef (a, t, p) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a(:)
+ type(m), target :: t(3,10)
+ type(m), pointer :: p(:,:)
+
+ allocate (a(5:15))
+ p => t
+ end subroutine
+
+ ! C binding version
+ subroutine testc (a, t, p) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a(:)
+ type(m), target :: t(3,10)
+ type(m), pointer :: p(:,:)
+
+ ! Call both the C and Fortran binding check functions
+ call checkc (a, t, p, .false.)
+ call checkf (a, t, p, .false.)
+
+ ! Allocate/associate and check again.
+ allocate (a(5))
+ p => t
+ call checkc (a, t, p, .true.)
+ call checkf (a, t, p, .true.)
+
+ ! Reset and check a third time.
+ deallocate (a)
+ p => NULL ()
+ call checkc (a, t, p, .false.)
+ call checkf (a, t, p, .false.)
+
+ ! Allocate/associate inside a function with Fortran binding.
+ call allocatef (a, t, p)
+ if (.not. allocated (a)) stop 301
+ if (.not. associated (p)) stop 302
+ if (lbound (a, 1) .ne. 5) stop 303
+ if (ubound (a, 1) .ne. 15) stop 304
+ deallocate (a)
+ p => NULL ()
+
+ ! Allocate/associate inside a function with C binding.
+ call allocatec (a, t, p)
+ if (.not. allocated (a)) stop 311
+ if (.not. associated (p)) stop 312
+ if (lbound (a, 1) .ne. 10) stop 313
+ if (ubound (a, 1) .ne. 20) stop 314
+ deallocate (a)
+ p => NULL ()
+
+ end subroutine
+
+ ! Fortran binding version
+ subroutine testf (a, t, p)
+ use iso_c_binding
+ use mm
+ type(m), allocatable :: a(:)
+ type(m), target :: t(3,10)
+ type(m), pointer :: p(:,:)
+
+ ! Call both the C and Fortran binding check functions
+ call checkc (a, t, p, .false.)
+ call checkf (a, t, p, .false.)
+
+ ! Allocate/associate and check again.
+ allocate (a(5))
+ p => t
+ call checkc (a, t, p, .true.)
+ call checkf (a, t, p, .true.)
+
+ ! Reset and check a third time.
+ deallocate (a)
+ p => NULL ()
+ call checkc (a, t, p, .false.)
+ call checkf (a, t, p, .false.)
+
+ ! Allocate/associate inside a function with Fortran binding.
+ call allocatef (a, t, p)
+ if (.not. allocated (a)) stop 401
+ if (.not. associated (p)) stop 402
+ if (lbound (a, 1) .ne. 5) stop 403
+ if (ubound (a, 1) .ne. 15) stop 404
+ deallocate (a)
+ p => NULL ()
+
+ ! Allocate/associate inside a function with C binding.
+ call allocatec (a, t, p)
+ if (.not. allocated (a)) stop 411
+ if (.not. associated (p)) stop 412
+ if (lbound (a, 1) .ne. 10) stop 413
+ if (ubound (a, 1) .ne. 20) stop 414
+ deallocate (a)
+ p => NULL ()
+
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/ff-descriptor-5.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ff-descriptor-5.f90
@@ -0,0 +1,61 @@
+! PR92482
+! { dg-do run }
+!
+! This program checks that passing arrays as assumed-length character
+! dummies to and from Fortran functions with C binding works.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ character(len=26,kind=C_CHAR) :: aa
+
+ call testc (aa)
+ call testf (aa)
+
+contains
+
+ ! C binding version
+
+ subroutine checkc (a) bind (c)
+ use iso_c_binding
+ character(len=*,kind=C_CHAR) :: a
+
+ if (rank (a) .ne. 0) stop 101
+ if (len (a) .ne. 26) stop 102
+ if (a .ne. 'abcdefghijklmnopqrstuvwxyz') stop 103
+ end subroutine
+
+ ! Fortran binding version
+ subroutine checkf (a)
+ use iso_c_binding
+ character(len=*,kind=C_CHAR) :: a
+
+ if (rank (a) .ne. 0) stop 201
+ if (len (a) .ne. 26) stop 202
+ if (a .ne. 'abcdefghijklmnopqrstuvwxyz') stop 203
+ end subroutine
+
+ ! C binding version
+ subroutine testc (a) bind (c)
+ use iso_c_binding
+ character(len=*,kind=C_CHAR) :: a
+
+ ! Call both the C and Fortran binding check functions
+ a = 'abcdefghijklmnopqrstuvwxyz'
+ call checkc (a)
+ call checkf (a)
+ end subroutine
+
+ ! Fortran binding version
+ subroutine testf (a)
+ use iso_c_binding
+ character(len=*,kind=C_CHAR) :: a
+
+ ! Call both the C and Fortran binding check functions
+ a = 'abcdefghijklmnopqrstuvwxyz'
+ call checkc (a)
+ call checkf (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/ff-descriptor-6.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ff-descriptor-6.f90
@@ -0,0 +1,71 @@
+! Reported as pr94070.
+! { dg-do run }
+!
+! This program checks that passing assumed-size arrays to
+! and from Fortran functions with C binding works.
+!
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ ! Assumed-size arrays are not passed by descriptor. What we'll do
+ ! for this test function is bind an assumed-rank dummy
+ ! to the assumed-size array. This is supposed to fill in the descriptor
+ ! with information about the array present at the call site.
+ interface
+ subroutine ctest (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ end subroutine
+ end interface
+
+ integer(C_INT), target :: aa(10,5:8)
+
+ ! To get an assumed-size array descriptor, we have to first pass the
+ ! fixed-size array to a Fortran function with an assumed-size dummy,
+ call ftest1 (aa)
+ call ftest2 (aa)
+ call ftest3 (aa)
+
+contains
+ subroutine ftest1 (a)
+ use iso_c_binding
+ integer(C_INT) :: a(10,*)
+ call testf (a)
+ call testc (a)
+ end subroutine
+ subroutine ftest2 (a)
+ use iso_c_binding
+ integer(C_INT) :: a(10,5:*)
+ call testf (a)
+ call testc (a)
+ end subroutine
+ subroutine ftest3 (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(10,1:*)
+ call testf (a)
+ call testc (a)
+ end subroutine
+
+ subroutine testf (a)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ if (rank (a) .ne. 2) stop 101
+ print *, size (a, 1), size (a, 2)
+ if (size (a, 1) .ne. 10) stop 102
+ if (size (a, 2) .ne. -1) stop 103
+ if (any (lbound (a) .eq. 0)) stop 104
+ end subroutine
+
+ subroutine testc (a) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(..)
+ if (rank (a) .ne. 2) stop 201
+ print *, size (a, 1), size (a, 2)
+ if (size (a, 1) .ne. 10) stop 202
+ if (size (a, 2) .ne. -1) stop 203
+ if (any (lbound (a) .eq. 0)) stop 204
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/ff-descriptor-7.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ff-descriptor-7.f90
@@ -0,0 +1,89 @@
+! { dg-do run }
+!
+! Test that arrays that may not be contiguous can be passed both ways
+! between Fortran subroutines with C and Fortran binding conventions.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ integer(C_INT), target :: aa(10,5)
+ integer(C_INT), target :: bb(10,10)
+
+ integer :: i, j, n
+
+ ! Test both C and Fortran binding.
+ n = 0
+ do j = 1, 10
+ do i = 1, 5
+ aa(j,i) = n
+ n = n + 1
+ end do
+ end do
+ call testc (transpose (aa))
+ call testf (transpose (aa))
+
+ bb = -1
+ n = 0
+ do j = 1, 10
+ do i = 2, 10, 2
+ bb(i,j) = n
+ n = n + 1
+ end do
+ end do
+ call testc (bb(2:10:2, :))
+ call testf (bb(2:10:2, :))
+
+contains
+
+ subroutine testc (a) bind (c)
+ use iso_c_binding
+ integer(C_INT), intent(in) :: a(:,:)
+ call checkc (a)
+ call checkf (a)
+ end subroutine
+
+ subroutine testf (a)
+ use iso_c_binding
+ integer(C_INT), intent(in) :: a(:,:)
+ call checkc (a)
+ call checkf (a)
+ end subroutine
+
+ subroutine checkc (a) bind (c)
+ use iso_c_binding
+ integer(C_INT), intent(in) :: a(:,:)
+ integer :: i, j, n
+
+ if (rank (a) .ne. 2) stop 101
+ if (size (a, 1) .ne. 5) stop 102
+ if (size (a, 2) .ne. 10) stop 103
+
+ n = 0
+ do j = 1, 10
+ do i = 1, 5
+ if (a(i,j) .ne. n) stop 104
+ n = n + 1
+ end do
+ end do
+ end subroutine
+
+ subroutine checkf (a)
+ use iso_c_binding
+ integer(C_INT), intent(in) :: a(:,:)
+ integer :: i, j, n
+
+ if (rank (a) .ne. 2) stop 101
+ if (size (a, 1) .ne. 5) stop 102
+ if (size (a, 2) .ne. 10) stop 103
+
+ n = 0
+ do j = 1, 10
+ do i = 1, 5
+ if (a(i,j) .ne. n) stop 104
+ n = n + 1
+ end do
+ end do
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/note-5-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/note-5-3.f90
@@ -0,0 +1,55 @@
+! { dg-do run }
+!
+! TS 29113
+! NOTE 5.3
+! The intrinsic inquiry function RANK can be used to inquire about the
+! rank of a data object. The rank of an assumed-rank object is zero if
+! the rank of the corresponding actual argument is zero.
+
+program test
+
+ integer :: scalar, array_1d(10), array_2d(3, 3)
+
+ call testit (scalar, array_1d, array_2d)
+
+contains
+
+ function test_rank (a)
+ integer :: test_rank
+ integer :: a(..)
+
+ test_rank = rank (a)
+ end function
+
+ subroutine testit (a0, a1, a2)
+ integer :: a0(..), a1(..), a2(..)
+
+ integer, target :: b0, b1(10), b2(3, 3)
+ integer, allocatable :: c0, c1(:), c2(:,:)
+ integer, pointer :: d0, d1(:), d2(:,:)
+
+ ! array descriptor passed from caller through testit to test_rank
+ if (test_rank (a0) .ne. 0) stop 100
+ if (test_rank (a1) .ne. 1) stop 101
+ if (test_rank (a2) .ne. 2) stop 102
+
+ ! array descriptor created locally here, fixed size
+ if (test_rank (b0) .ne. 0) stop 200
+ if (test_rank (b1) .ne. 1) stop 201
+ if (test_rank (b2) .ne. 2) stop 202
+
+ ! allocatable arrays don't actually have to be allocated.
+ if (test_rank (c0) .ne. 0) stop 300
+ if (test_rank (c1) .ne. 1) stop 301
+ if (test_rank (c2) .ne. 2) stop 302
+
+ ! pointer arrays do need to point at something.
+ d0 => b0
+ d1 => b1
+ d2 => b2
+ if (test_rank (d0) .ne. 0) stop 400
+ if (test_rank (d1) .ne. 1) stop 401
+ if (test_rank (d2) .ne. 2) stop 402
+
+ end subroutine
+end program
Index: Fortran/gfortran/regression/c-interop/note-5-4-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/note-5-4-c.c
@@ -0,0 +1,10 @@
+#include
+
+extern int test_rank (CFI_cdesc_t *a);
+
+int test_rank (CFI_cdesc_t *a)
+{
+ if (!a)
+ return -1; /* Should not happen. */
+ return a->rank;
+}
Index: Fortran/gfortran/regression/c-interop/note-5-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/note-5-4.f90
@@ -0,0 +1,63 @@
+! { dg-do run }
+! { dg-additional-sources note-5-4-c.c }
+!
+! TS 29113
+! NOTE 5.4
+! Assumed rank is an attribute of a Fortran dummy argument. When a C
+! function is invoked with an actual argument that corresponds to an
+! assumed-rank dummy argument in a Fortran interface for that C function,
+! the corresponding formal parameter is the address of a descriptor of
+! type CFI_cdesc_t (8.7). The rank member of the descriptor provides the
+! rank of the actual argument. The C function should therefore be able
+! to handle any rank. On each invocation, the rank is available to it.
+
+program test
+
+ interface
+ function test_rank (a) bind (c, name="test_rank")
+ integer :: test_rank
+ integer :: a(..)
+ end function
+ end interface
+
+ integer :: scalar, array_1d(10), array_2d(3, 3)
+
+ call testit (scalar, array_1d, array_2d)
+
+contains
+
+ subroutine testit (a0, a1, a2)
+ integer :: a0(..), a1(..), a2(..)
+
+ integer, target :: b0, b1(10), b2(3, 3)
+ integer, allocatable :: c0, c1(:), c2(:,:)
+ integer, pointer :: d0, d1(:), d2(:,:)
+
+ ! array descriptor passed from caller through testit to test_rank
+ if (test_rank (a0) .ne. 0) stop 100
+ if (test_rank (a1) .ne. 1) stop 101
+ if (test_rank (a2) .ne. 2) stop 102
+
+ ! array descriptor created locally here, fixed size
+ if (test_rank (b0) .ne. 0) stop 200
+ if (test_rank (b1) .ne. 1) stop 201
+ if (test_rank (b2) .ne. 2) stop 202
+
+ ! allocatables
+ allocate (c0)
+ allocate (c1 (10))
+ allocate (c2 (3, 3))
+ if (test_rank (c0) .ne. 0) stop 300
+ if (test_rank (c1) .ne. 1) stop 301
+ if (test_rank (c2) .ne. 2) stop 302
+
+ ! pointers
+ d0 => b0
+ d1 => b1
+ d2 => b2
+ if (test_rank (d0) .ne. 0) stop 400
+ if (test_rank (d1) .ne. 1) stop 401
+ if (test_rank (d2) .ne. 2) stop 402
+
+ end subroutine
+end program
Index: Fortran/gfortran/regression/c-interop/optional-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/optional-c.c
@@ -0,0 +1,82 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ftest (int n, CFI_cdesc_t *a, int *b, char *c, double *d);
+extern void ctest1 (CFI_cdesc_t *a, int *b, char *c, double *d);
+extern void ctest2 (int n, CFI_cdesc_t *a, int *b, char *c, double *d);
+
+static void *aa;
+static int *bb;
+static char *cc;
+static double *dd;
+
+extern void
+ctest1 (CFI_cdesc_t *a, int *b, char *c, double *d)
+{
+ /* Cache all the pointer arguments for later use by ctest2. */
+ aa = a->base_addr;
+ bb = b;
+ cc = c;
+ dd = d;
+
+ /* Test calling back into Fortran. */
+ ftest (0, NULL, NULL, NULL, NULL);
+ ftest (1, a, NULL, NULL, NULL);
+ ftest (2, a, b, NULL, NULL);
+ ftest (3, a, b, c, NULL);
+ ftest (4, a, b, c, d);
+}
+
+extern void
+ctest2 (int n, CFI_cdesc_t *a, int *b, char *c, double *d)
+{
+ if (n >= 1)
+ {
+ if (!a)
+ abort ();
+ if (a->base_addr != aa)
+ abort ();
+ }
+ else
+ if (a)
+ abort ();
+
+ if (n >= 2)
+ {
+ if (!b)
+ abort ();
+ if (*b != *bb)
+ abort ();
+ }
+ else
+ if (b)
+ abort ();
+
+ if (n >= 3)
+ {
+ if (!c)
+ abort ();
+ if (*c != *cc)
+ abort ();
+ }
+ else
+ if (c)
+ abort ();
+
+ if (n >= 4)
+ {
+ if (!d)
+ abort ();
+ if (*d != *dd)
+ abort ();
+ }
+ else
+ if (d)
+ abort ();
+
+}
+
+
Index: Fortran/gfortran/regression/c-interop/optional.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/optional.f90
@@ -0,0 +1,114 @@
+! { dg-do run }
+! { dg-additional-sources "optional-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! TS 29113
+! 8.7 An absent actual argument in a reference to an interoperable
+! procedure is indicated by a corresponding formal parameter with the
+! value of a null pointer. An absent optional dummy argument in a
+! reference to an interoperable procedure from a C function is indicated
+! by a corresponding argument with the value of a null pointer.
+
+module m
+ use iso_c_binding
+ integer(C_INT) :: aa(32)
+ integer(C_INT) :: bb
+ character(C_CHAR) :: cc
+ real(C_DOUBLE) :: dd
+end module
+
+subroutine ftest (n, a, b, c, d) bind (c)
+ use iso_c_binding
+ use m
+ implicit none
+ integer(C_INT), value :: n
+ integer(C_INT), optional :: a(:)
+ integer(C_INT), optional :: b
+ character(C_CHAR), optional :: c
+ real(C_DOUBLE), optional :: d
+
+ if (n .ge. 1) then
+ if (.not. present (a)) stop 101
+ if (any (a .ne. aa)) stop 201
+ else
+ if (present (a)) stop 301
+ end if
+
+ if (n .ge. 2) then
+ if (.not. present (b)) stop 102
+ if (b .ne. bb) stop 201
+ else
+ if (present (b)) stop 302
+ end if
+
+ if (n .ge. 3) then
+ if (.not. present (c)) stop 103
+ if (c .ne. cc) stop 201
+ else
+ if (present (c)) stop 303
+ end if
+
+ if (n .ge. 4) then
+ if (.not. present (d)) stop 104
+ if (d .ne. dd) stop 201
+ else
+ if (present (d)) stop 304
+ end if
+end subroutine
+
+program testit
+ use iso_c_binding
+ use m
+ implicit none
+
+ interface
+ subroutine ctest1 (a, b, c, d) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: a(:)
+ integer(C_INT) :: b
+ character(C_CHAR) :: c
+ real(C_DOUBLE) :: d
+ end subroutine
+ subroutine ctest2 (n, a, b, c, d) bind (c)
+ use iso_c_binding
+ integer(C_INT), value :: n
+ integer(C_INT), optional :: a(:)
+ integer(C_INT), optional :: b
+ character(C_CHAR), optional :: c
+ real(C_DOUBLE), optional :: d
+ end subroutine
+ subroutine ftest (n, a, b, c, d) bind (c)
+ use iso_c_binding
+ integer(C_INT), value :: n
+ integer(C_INT), optional :: a(:)
+ integer(C_INT), optional :: b
+ character(C_CHAR), optional :: c
+ real(C_DOUBLE), optional :: d
+ end subroutine
+ end interface
+
+
+ ! Initialize the variables above.
+ integer :: i
+ do i = 1, 32
+ aa(i) = i
+ end do
+ bb = 42
+ cc = '$'
+ dd = acos(-1.D0)
+
+ call ftest (0)
+ call ftest (1, aa)
+ call ftest (2, aa, bb)
+ call ftest (3, aa, bb, cc)
+ call ftest (4, aa, bb, cc, dd)
+
+ call ctest1 (aa, bb, cc, dd)
+ call ctest2 (0)
+ call ctest2 (1, aa)
+ call ctest2 (2, aa, bb)
+ call ctest2 (3, aa, bb, cc)
+ call ctest2 (4, aa, bb, cc, dd)
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/pr103287-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103287-1.f90
@@ -0,0 +1,9 @@
+! { dg-do compile }
+
+subroutine g
+ call s([1])
+end
+subroutine h(x)
+ integer, pointer :: x(..)
+ call s(x) ! { dg-error "Assumed-rank argument requires an explicit interface" }
+end
Index: Fortran/gfortran/regression/c-interop/pr103287-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103287-2.f90
@@ -0,0 +1,9 @@
+! { dg-do compile }
+
+subroutine g
+ call s(1)
+end
+subroutine h(x)
+ integer, pointer :: x(..)
+ call s(x) ! { dg-error "Assumed-rank argument requires an explicit interface" }
+end
Index: Fortran/gfortran/regression/c-interop/pr103390-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-1.f90
@@ -0,0 +1,23 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! This program used to ICE in gimplification on the call to S, because it
+! was trying to copy out the array after the call to something that wasn't
+! an lvalue.
+
+program p
+ integer, pointer :: z(:)
+ integer, target :: x(3) = [1, 2, 3]
+ z => x
+ call s(shape(z))
+contains
+ subroutine s(x) bind(c)
+ integer, contiguous :: x(:)
+ end
+end
+
+! It should not emit any copy loops, just the loop for inlining SHAPE.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 1 "original" } }
+
+! It should not emit code to check the contiguous property.
+! { dg-final { scan-tree-dump-not "contiguous\\.\[0-9\]+" "original" } }
Index: Fortran/gfortran/regression/c-interop/pr103390-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-2.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! Check that copy loops to ensure contiguity of transpose result are
+! still generated after fixing pr103390, and that it does not ICE.
+
+program p
+ integer, pointer :: z(:,:)
+ integer, target :: x(3,3) = reshape ([1, 2, 3, 4, 5, 6, 7, 8, 9], shape(x))
+ z => x
+ call s(transpose(z))
+contains
+ subroutine s(x) bind(c)
+ integer, contiguous :: x(:,:)
+ end
+end
+
+! Expect 2 nested copy loops both before and after the call to S.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 4 "original" } }
+
Index: Fortran/gfortran/regression/c-interop/pr103390-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-3.f90
@@ -0,0 +1,29 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! Check that copy loops to ensure contiguity of the result of a function
+! that returns a non-pointer array are generated properly after fixing
+! pr103390, and that it does not ICE. In this case no copying is required.
+
+program p
+ integer, pointer :: z(:)
+ integer, target :: x(3) = [1, 2, 3]
+ z => x
+ call s(i(z))
+contains
+ function i(x)
+ integer :: i(3)
+ integer, pointer :: x(:)
+ i = x
+ end
+ subroutine s(x) bind(c)
+ integer, contiguous :: x(:)
+ end
+end
+
+! Expect one loop to copy the array contents to a temporary in function i.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 1 "original" } }
+
+! It should not emit code to check the contiguous property.
+! { dg-final { scan-tree-dump-not "contiguous\\.\[0-9\]+" "original" } }
+
Index: Fortran/gfortran/regression/c-interop/pr103390-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-4.f90
@@ -0,0 +1,25 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! Check that copy loops to ensure contiguity of the result of a function
+! that returns a pointer to an array are generated properly after fixing
+! pr103390, and that it does not ICE.
+
+program p
+ integer, pointer :: z(:)
+ integer, target :: x(3) = [1, 2, 3]
+ z => x
+ call s(i(z))
+contains
+ function i(x)
+ integer, pointer :: i(:)
+ integer, pointer :: x(:)
+ i => x
+ end
+ subroutine s(x) bind(c)
+ integer, contiguous :: x(:)
+ end
+end
+
+! Expect a copy loop both before and after the call to S.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 2 "original" } }
Index: Fortran/gfortran/regression/c-interop/pr103390-5.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-5.f90
@@ -0,0 +1,26 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! Check that copy loops to ensure contiguity of the result of a function
+! that returns a pointer to an array are generated properly after fixing
+! pr103390, and that it does not ICE. This variant is for an intent(in)
+! dummy argument so no copy-out is needed, only copy-in.
+
+program p
+ integer, pointer :: z(:)
+ integer, target :: x(3) = [1, 2, 3]
+ z => x
+ call s(i(z))
+contains
+ function i(x)
+ integer, pointer :: i(:)
+ integer, pointer :: x(:)
+ i => x
+ end
+ subroutine s(x) bind(c)
+ integer, contiguous, intent(in) :: x(:)
+ end
+end
+
+! Expect a copy loop before the call to S.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 1 "original" } }
Index: Fortran/gfortran/regression/c-interop/pr103390-6.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-6.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! Check that copy loops to ensure contiguity of transpose result are
+! generated properly after fixing pr103390, and that it does not ICE.
+! This variant is for an intent(in) dummy argument so no copy-out
+! is needed, only copy-in.
+
+program p
+ integer, pointer :: z(:,:)
+ integer, target :: x(3,3) = reshape ([1, 2, 3, 4, 5, 6, 7, 8, 9], shape(x))
+ z => x
+ call s(transpose(z))
+contains
+ subroutine s(x) bind(c)
+ integer, contiguous, intent(in) :: x(:,:)
+ end
+end
+
+! Expect 2 nested copy loops before the call to S.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 2 "original" } }
+
Index: Fortran/gfortran/regression/c-interop/pr103390-7.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-7.f90
@@ -0,0 +1,19 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! Check that copy loops to ensure contiguity of the result of an array
+! section expression are generated properly after fixing pr103390, and
+! that it does not ICE.
+
+program p
+ integer, pointer :: z(:)
+ integer :: A(5) = [1, 2, 3, 4, 5]
+ call s(A(::2))
+contains
+ subroutine s(x) bind(c)
+ integer, contiguous :: x(:)
+ end
+end
+
+! Expect copy loops before and after the call to S.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 2 "original" } }
Index: Fortran/gfortran/regression/c-interop/pr103390-8.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-8.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! Check that copy loops to ensure contiguity of the result of an array
+! section expression are generated properly after fixing pr103390,
+! and that it does not ICE. This case is for an intent(in)
+! dummy so no copy-out should occur, only copy-in.
+
+program p
+ integer, pointer :: z(:)
+ integer, parameter :: A(5) = [1, 2, 3, 4, 5]
+ call s(A(::2))
+contains
+ subroutine s(x) bind(c)
+ integer, contiguous, intent(in) :: x(:)
+ end
+end
+
+! Expect a copy loop before the call to S.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 1 "original" } }
Index: Fortran/gfortran/regression/c-interop/pr103390-9.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/pr103390-9.f90
@@ -0,0 +1,26 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! Check that copy loops to ensure contiguity of the result of an elemental
+! array-valued expression are generated properly after fixing pr103390,
+! and that it does not ICE.
+
+program p
+ integer, pointer :: z(:)
+ integer :: a(3) = [1, 2, 3];
+ integer :: b(3) = [4, 5, 6];
+ call s(a + b);
+contains
+ subroutine s(x) bind(c)
+ integer, contiguous :: x(:)
+ end
+end
+
+! We only expect one loop before the call, to fill in the contiguous
+! temporary. No copy-out is needed since the temporary is effectively
+! an rvalue.
+! { dg-final { scan-tree-dump-times "while \\(1\\)" 1 "original" } }
+
+! It should not emit code to check the contiguous property.
+! { dg-final { scan-tree-dump-not "contiguous\\.\[0-9\]+" "original" } }
+
Index: Fortran/gfortran/regression/c-interop/rank-class.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/rank-class.f90
@@ -0,0 +1,88 @@
+! { dg-do run }
+!
+! TS 29113
+! 7.2 RANK (A)
+! Description. Rank of a data object.
+! Class. Inquiry function.
+! Argument.
+! A shall be a scalar or array of any type.
+! Result Characteristics. Default integer scalar.
+! Result Value. The result is the rank of A.
+
+module m
+
+ type :: base
+ integer :: a, b
+ end type
+
+ type, extends (base) :: derived
+ integer :: c
+ end type
+end module
+
+program test
+ use m
+
+ ! Define some arrays for testing.
+ type(derived), target :: x1(5)
+ type(derived) :: y1(0:9)
+ type(derived), pointer :: p1(:)
+ type(derived), allocatable :: a1(:)
+ type(derived), target :: x3(2,3,4)
+ type(derived) :: y3(0:1,-3:-1,4)
+ type(derived), pointer :: p3(:,:,:)
+ type(derived), allocatable :: a3(:,:,:)
+ type(derived) :: x
+
+ ! Test the 1-dimensional arrays.
+ if (rank (x1) .ne. 1) stop 201
+ call testit (x1, 1)
+ if (rank (y1) .ne. 1) stop 202
+ call testit (y1, 1)
+ if (rank (p1) .ne. 1) stop 203
+ p1 => x1
+ call testit (p1, 1)
+ if (rank (p1) .ne. 1) stop 204
+ if (rank (a1) .ne. 1) stop 205
+ allocate (a1(5))
+ if (rank (a1) .ne. 1) stop 206
+ call testit (a1, 1)
+
+ ! Test the multi-dimensional arrays.
+ if (rank (x3) .ne. 3) stop 207
+ call testit (x3, 3)
+ if (rank (y3) .ne. 3) stop 208
+ if (rank (p3) .ne. 3) stop 209
+ p3 => x3
+ call testit (p3, 3)
+ if (rank (p3) .ne. 3) stop 210
+ if (rank (a3) .ne. 3) stop 211
+ allocate (a3(2,3,4))
+ call testit (a3, 3)
+ if (rank (a3) .ne. 3) stop 212
+
+ ! Test scalars.
+ if (rank (x) .ne. 0) stop 213
+ call testit (x, 0)
+ call test0 (x)
+ if (rank (x1(1)) .ne. 0) stop 215
+ call test0 (x1(1))
+
+contains
+
+ subroutine testit (a, r)
+ use m
+ class(base) :: a(..)
+ integer :: r
+
+ if (r .ne. rank(a)) stop 101
+ end subroutine
+
+ subroutine test0 (a)
+ use m
+ class(base) :: a(..)
+ if (rank (a) .ne. 0) stop 103
+ call testit (a, 0)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/rank.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/rank.f90
@@ -0,0 +1,99 @@
+! { dg-do run }
+!
+! TS 29113
+! 7.2 RANK (A)
+! Description. Rank of a data object.
+! Class. Inquiry function.
+! Argument.
+! A shall be a scalar or array of any type.
+! Result Characteristics. Default integer scalar.
+! Result Value. The result is the rank of A.
+
+program test
+
+ ! Define some arrays for testing.
+ integer, target :: x1(5)
+ integer :: y1(0:9)
+ integer, pointer :: p1(:)
+ integer, allocatable :: a1(:)
+ integer, target :: x3(2,3,4)
+ integer :: y3(0:1,-3:-1,4)
+ integer, pointer :: p3(:,:,:)
+ integer, allocatable :: a3(:,:,:)
+ integer :: x
+
+ ! Test the 1-dimensional arrays.
+ if (rank (x1) .ne. 1) stop 201
+ call testit (x1, 1)
+ call test1 (x1)
+ if (rank (y1) .ne. 1) stop 202
+ call testit (y1, 1)
+ call test1 (y1)
+ if (rank (p1) .ne. 1) stop 203
+ p1 => x1
+ call testit (p1, 1)
+ if (rank (p1) .ne. 1) stop 204
+ call test1 (p1)
+ if (rank (a1) .ne. 1) stop 205
+ allocate (a1(5))
+ if (rank (a1) .ne. 1) stop 206
+ call testit (a1, 1)
+ call test1 (a1)
+
+ ! Test the multi-dimensional arrays.
+ if (rank (x3) .ne. 3) stop 207
+ call testit (x3, 3)
+ call test1 (x3)
+ call test3 (x3, 1, 2, 1, 3)
+ if (rank (y3) .ne. 3) stop 208
+ call test3 (y3, 0, 1, -3, -1)
+ if (rank (p3) .ne. 3) stop 209
+ p3 => x3
+ call testit (p3, 3)
+ call test1 (p3)
+ if (rank (p3) .ne. 3) stop 210
+ call test3 (p3, 1, 2, 1, 3)
+ if (rank (a3) .ne. 3) stop 211
+ allocate (a3(2,3,4))
+ call testit (a3, 3)
+ call test1 (a3)
+ if (rank (a3) .ne. 3) stop 212
+ call test3 (a3, 1, 2, 1, 3)
+
+ ! Test scalars.
+ if (rank (x) .ne. 0) stop 213
+ call testit (x, 0)
+ call test0 (x)
+ if (rank (-1) .ne. 0) stop 214
+ call test0 (-1)
+ if (rank (x1(1)) .ne. 0) stop 215
+ call test0 (x1(1))
+
+contains
+
+ subroutine testit (a, r)
+ integer :: a(..)
+ integer :: r
+
+ if (r .ne. rank(a)) stop 101
+ end subroutine
+
+ subroutine test0 (a)
+ integer :: a(..)
+ if (rank (a) .ne. 0) stop 103
+ call testit (a, 0)
+ end subroutine
+
+ subroutine test1 (a)
+ integer :: a(*)
+ call testit (a, 1)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2)
+ implicit none
+ integer :: l1, u1, l2, u2
+ integer :: a(l1:u1, l2:u2, *)
+ call testit (a, 3)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/removed-restrictions-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/removed-restrictions-1.f90
@@ -0,0 +1,41 @@
+! { dg-do compile}
+!
+! TS 29113
+! 8.1 Removed restrictions on ISO_C_BINDING module procedures
+!
+! The subroutine C_F_POINTER from the intrinsic module ISO_C_BINDING has
+! the restriction in ISO/IEC 1539- 1:2010 that if FPTR is an array, it
+! shall be of interoperable type.
+!
+! [...]
+!
+! These restrictions are removed.
+
+module m
+ use ISO_C_BINDING
+ implicit none
+
+ ! An obvious example of a type that isn't interoperable is a
+ ! derived type without a bind(c) clause.
+
+ integer :: buflen
+ parameter (buflen=256)
+
+ type :: packet
+ integer :: size
+ integer(1) :: buf(buflen)
+ end type
+
+contains
+
+ subroutine test (ptr, n, packets)
+ type(C_PTR), intent(in) :: ptr
+ integer, intent(in) :: n
+ type(packet), pointer, intent(out) :: packets(:)
+
+ integer :: s(1)
+ s(1) = n
+
+ call c_f_pointer (ptr, packets, s)
+ end subroutine
+end module
Index: Fortran/gfortran/regression/c-interop/removed-restrictions-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/removed-restrictions-2.f90
@@ -0,0 +1,35 @@
+! { dg-do compile}
+!
+! TS 29113
+! 8.1 Removed restrictions on ISO_C_BINDING module procedures
+!
+! The function C_F_PROCPOINTER from the intrinsic module ISO_C_BINDING
+! has the restriction in ISO/IEC 1539-1:2010 that CPTR and FPTR shall
+! not be the C address and interface of a noninteroperable Fortran
+! procedure.
+!
+! [...]
+!
+! These restrictions are removed.
+
+module m
+ use ISO_C_BINDING
+ implicit none
+
+ ! Declare a non-interoperable Fortran procedure interface.
+ abstract interface
+ function foo (x, y)
+ integer :: foo
+ integer, intent (in) :: x, y
+ end function
+ end interface
+
+contains
+
+ subroutine test (cptr, fptr)
+ type(C_FUNPTR), intent(in) :: cptr
+ procedure (foo), pointer, intent(out) :: fptr
+
+ call c_f_procpointer (cptr, fptr)
+ end subroutine
+end module
Index: Fortran/gfortran/regression/c-interop/removed-restrictions-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/removed-restrictions-3.f90
@@ -0,0 +1,37 @@
+! { dg-do compile}
+!
+! TS 29113
+! 8.1 Removed restrictions on ISO_C_BINDING module procedures
+!
+! The function C_LOC from the intrinsic module ISO_C_BINDING has the
+! restriction in ISO/IEC 1539-1:2010 that if X is an array, it shall
+! be of interoperable type.
+!
+! [...]
+!
+! These restrictions are removed.
+
+module m
+ use ISO_C_BINDING
+ implicit none
+
+ ! An obvious example of a type that isn't interoperable is a
+ ! derived type without a bind(c) clause.
+
+ integer :: buflen
+ parameter (buflen=256)
+
+ type :: packet
+ integer :: size
+ integer(1) :: buf(buflen)
+ end type
+
+contains
+
+ subroutine test (packets, ptr)
+ type(packet), pointer, intent(in) :: packets(:)
+ type(C_PTR), intent(out) :: ptr
+
+ ptr = c_loc (packets)
+ end subroutine
+end module
Index: Fortran/gfortran/regression/c-interop/removed-restrictions-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/removed-restrictions-4.f90
@@ -0,0 +1,34 @@
+! { dg-do compile}
+!
+! TS 29113
+! 8.1 Removed restrictions on ISO_C_BINDING module procedures
+!
+! [...]
+!
+! The function C_FUNLOC from the intrinsic module ISO_C_BINDING has
+! the restriction in ISO/IEC 1539-1:2010 that its argument shall be
+! interoperable.
+!
+! These restrictions are removed.
+
+module m
+ use ISO_C_BINDING
+ implicit none
+
+ ! Declare a non-interoperable Fortran procedure interface.
+ abstract interface
+ function foo (x, y)
+ integer :: foo
+ integer, intent (in) :: x, y
+ end function
+ end interface
+
+contains
+
+ subroutine test (fptr, cptr)
+ procedure (foo), pointer, intent(in) :: fptr
+ type(C_FUNPTR), intent(out) :: cptr
+
+ cptr = c_funloc (fptr)
+ end subroutine
+end module
Index: Fortran/gfortran/regression/c-interop/section-1-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-1-c.c
@@ -0,0 +1,135 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *a, int lb, int ub, int s, CFI_cdesc_t *r);
+
+/* Take a section of array A. OFF is the start index of A on the Fortran
+ side and the bounds LB and UB for the section to take are relative to
+ that base index. Store the result in R, which is supposed to be a pointer
+ array with lower bound 1. */
+
+void
+ctest (CFI_cdesc_t *a, int lb, int ub, int s, CFI_cdesc_t *r)
+{
+ CFI_index_t lb_array[1], ub_array[1], s_array[1];
+ CFI_index_t i, o;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ fprintf (stderr, "\n%s: lb=%d ub=%d s=%d\n",
+ (a->attribute == CFI_attribute_other) ? "non-pointer" : "pointer",
+ lb, ub, s);
+ dump_CFI_cdesc_t (a);
+ dump_CFI_cdesc_t (r);
+
+ /* Make sure we got a valid input descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(int))
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (a->type != CFI_type_int)
+ abort ();
+ if (a->attribute == CFI_attribute_other)
+ {
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ /* Adjust the 1-based bounds. */
+ lb = lb - 1;
+ ub = ub - 1;
+ }
+ /* For pointer arrays, the bounds use the same indexing as the lower
+ bound in the array descriptor. */
+
+ /* Make sure we got a valid output descriptor. */
+ if (r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(int))
+ abort ();
+ if (r->rank != 1)
+ abort ();
+ if (r->type != CFI_type_int)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+
+ /* Create an array section. */
+ lb_array[0] = lb;
+ ub_array[0] = ub;
+ s_array[0] = s;
+
+ check_CFI_status ("CFI_section",
+ CFI_section (r, a, lb_array, ub_array, s_array));
+
+ /* Check that the output descriptor is correct. */
+ dump_CFI_cdesc_t (r);
+ if (!r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(int))
+ abort ();
+ if (r->rank != 1)
+ abort ();
+ if (r->type != CFI_type_int)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+
+ /* Check the contents of the output array. */
+#if 0
+ for (o = r->dim[0].lower_bound, i = lb;
+ (s > 0 ? i <= ub : i >= ub);
+ o++, i += s)
+ {
+ int *input = (int *) CFI_address (a, &i);
+ int *output = (int *) CFI_address (r, &o);
+ fprintf (stderr, "a(%d) = %d, r(%d) = %d\n",
+ (int)i, *input, (int)o, *output);
+ }
+#endif
+ for (o = r->dim[0].lower_bound, i = lb;
+ (s > 0 ? i <= ub : i >= ub);
+ o++, i += s)
+ {
+ int *input = (int *) CFI_address (a, &i);
+ int *output = (int *) CFI_address (r, &o);
+ if (*input != *output)
+ abort ();
+ }
+
+ /* Force the output array to be 1-based. */
+ lb_array[0] = 1;
+ check_CFI_status ("CFI_setpointer", CFI_setpointer (r, r, lb_array));
+ /* Check that the output descriptor is correct. */
+ dump_CFI_cdesc_t (r);
+ if (!r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(int))
+ abort ();
+ if (r->rank != 1)
+ abort ();
+ if (r->type != CFI_type_int)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+ if (r->dim[0].lower_bound != 1)
+ abort ();
+
+ /* Check the contents of the output array again. */
+ for (o = r->dim[0].lower_bound, i = lb;
+ (s > 0 ? i <= ub : i >= ub);
+ o++, i += s)
+ {
+ int *input = (int *) CFI_address (a, &i);
+ int *output = (int *) CFI_address (r, &o);
+ if (*input != *output)
+ abort ();
+ }
+
+}
+
+
+
Index: Fortran/gfortran/regression/c-interop/section-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-1.f90
@@ -0,0 +1,71 @@
+! { dg-do run }
+! { dg-additional-sources "section-1-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests basic use of the CFI_section C library function on
+! a 1-dimensional non-pointer/non-allocatable array, passed as an
+! assumed-shape dummy.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (a, lb, ub, s, r) bind (c)
+ use iso_c_binding
+ integer(C_INT), target :: a(:)
+ integer(C_INT), value :: lb, ub, s
+ integer(C_INT), pointer, intent(out) :: r(:)
+ end subroutine
+
+ end interface
+
+ integer(C_INT), target :: aa(32)
+ integer :: i
+
+ ! Initialize the test array by numbering its elements.
+ do i = 1, 32
+ aa(i) = i
+ end do
+
+ ! Try some cases with non-pointer input arrays.
+ call test (aa, 1, 32, 5, 13, 2) ! basic test
+ call test (aa, 4, 35, 5, 13, 2) ! non-default lower bound
+ call test (aa, 1, 32, 32, 16, -2) ! negative step
+
+contains
+
+ ! Test function for non-pointer array AA.
+ ! LO and HI are the bounds for the entire array.
+ ! LB, UB, and S describe the section to take, and use the
+ ! same indexing as LO and HI.
+ subroutine test (aa, lo, hi, lb, ub, s)
+ integer :: aa(lo:hi)
+ integer :: lo, hi, lb, ub, s
+
+ integer(C_INT), pointer :: rr(:)
+ integer :: i, o
+
+ ! Call the C function to put a section in rr.
+ ! The C function expects the section bounds to be 1-based.
+ nullify (rr)
+ call ctest (aa, lb - lo + 1, ub - lo + 1, s, rr)
+
+ ! Make sure the original array has not been modified.
+ do i = lo, hi
+ if (aa(i) .ne. i - lo + 1) stop 103
+ end do
+
+ ! Make sure the output array has the expected bounds and elements.
+ if (.not. associated (rr)) stop 111
+ if (lbound (rr, 1) .ne. 1) stop 112
+ if (ubound (rr, 1) .ne. (ub - lb)/s + 1) stop 113
+ o = 1
+ do i = lb, ub, s
+ if (rr(o) .ne. i - lo + 1) stop 114
+ o = o + 1
+ end do
+ end subroutine
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/section-1p.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-1p.f90
@@ -0,0 +1,75 @@
+! PR 101310
+! { dg-do run }
+! { dg-additional-sources "section-1-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests basic use of the CFI_section C library function on
+! a 1-dimensional pointer array.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest (p, lb, ub, s, r) bind (c)
+ use iso_c_binding
+ integer(C_INT), pointer :: p(:)
+ integer(C_INT), value :: lb, ub, s
+ integer(C_INT), pointer, intent(out) :: r(:)
+ end subroutine
+
+ end interface
+
+ integer(C_INT), target :: aa(32)
+ integer :: i
+
+ ! Initialize the test array by numbering its elements.
+ do i = 1, 32
+ aa(i) = i
+ end do
+
+ call test_p (aa, 0, 31, 15, 24, 3) ! zero lower bound
+ call test_p (aa, 1, 32, 16, 25, 3) ! non-zero lower bound
+ call test_p (aa, 4, 35, 16, 25, 3) ! some other lower bound
+ call test_p (aa, 1, 32, 32, 16, -2) ! negative step
+ stop
+
+contains
+
+ ! Test function for non-pointer array AA.
+ ! LO and HI are the bounds for the entire array.
+ ! LB, UB, and S describe the section to take, and use the
+ ! same indexing as LO and HI.
+ subroutine test_p (aa, lo, hi, lb, ub, s)
+ integer, target :: aa(1:hi-lo+1)
+ integer :: lo, hi, lb, ub, s
+
+ integer(C_INT), pointer :: pp(:), rr(:)
+ integer :: i, o
+
+ pp(lo:hi) => aa
+ if (lbound (pp, 1) .ne. lo) stop 121
+ if (ubound (pp, 1) .ne. hi) stop 122
+ nullify (rr)
+ call ctest (pp, lb, ub, s, rr)
+
+ ! Make sure the input pointer array has not been modified.
+ if (lbound (pp, 1) .ne. lo) stop 144
+ if (ubound (pp, 1) .ne. hi) stop 145
+ do i = lo, hi
+ if (pp(i) .ne. i - lo + 1) stop 146
+ end do
+
+ ! Make sure the output array has the expected bounds and elements.
+ if (.not. associated (rr)) stop 151
+ if (lbound (rr, 1) .ne. 1) stop 152
+ if (ubound (rr, 1) .ne. (ub - lb)/s + 1) stop 153
+ o = 1
+ do i = lb, ub, s
+ if (rr(o) .ne. i - lo + 1) stop 154
+ o = o + 1
+ end do
+ end subroutine
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/section-2-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-2-c.c
@@ -0,0 +1,175 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+struct m {
+ int x, y;
+};
+
+extern void ctest (CFI_cdesc_t *a, int lb0, int lb1,
+ int ub0, int ub1, int s0, int s1, CFI_cdesc_t *r);
+
+/* Take a section of array A. OFF is the start index of A on the Fortran
+ side and the bounds LB and UB for the section to take are relative to
+ that base index. Store the result in R, which is supposed to be a pointer
+ array with lower bound 1. */
+
+void
+ctest (CFI_cdesc_t *a, int lb0, int lb1,
+ int ub0, int ub1, int s0, int s1, CFI_cdesc_t *r)
+{
+ CFI_index_t lb_array[2], ub_array[2], s_array[2];
+ int i0, i1, o0, o1;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ fprintf (stderr, "\n%s: lb0=%d lb1=%d ub0=%d ub1=%d s0=%d s1=%d\n",
+ (a->attribute == CFI_attribute_other) ? "non-pointer" : "pointer",
+ lb0, lb1, ub0, ub1, s0, s1);
+ if (lb0 == ub0 || lb1 == ub1)
+ abort ();
+ dump_CFI_cdesc_t (a);
+ dump_CFI_cdesc_t (r);
+
+ /* Make sure we got a valid input descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(struct m))
+ abort ();
+ if (a->rank != 2)
+ abort ();
+ if (a->type != CFI_type_struct)
+ abort ();
+ if (a->attribute == CFI_attribute_other)
+ {
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ /* Adjust the 1-based bounds. */
+ lb0 = lb0 - 1;
+ lb1 = lb1 - 1;
+ ub0 = ub0 - 1;
+ ub1 = ub1 - 1;
+ }
+ /* For pointer arrays, the bounds use the same indexing as the lower
+ bound in the array descriptor. */
+
+ /* Make sure we got a valid output descriptor. */
+ if (r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(struct m))
+ abort ();
+ if (r->rank != 2)
+ abort ();
+ if (r->type != CFI_type_struct)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+
+ /* Create an array section. */
+ lb_array[0] = lb0;
+ lb_array[1] = lb1;
+ ub_array[0] = ub0;
+ ub_array[1] = ub1;
+ s_array[0] = s0;
+ s_array[1] = s1;
+
+ check_CFI_status ("CFI_section",
+ CFI_section (r, a, lb_array, ub_array, s_array));
+
+ /* Check that the output descriptor is correct. */
+ dump_CFI_cdesc_t (r);
+ if (!r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(struct m))
+ abort ();
+ if (r->rank != 2)
+ abort ();
+ if (r->type != CFI_type_struct)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+
+ /* Check the contents of the output array. */
+#if 0
+ for (o1 = r->dim[1].lower_bound, i1 = lb1;
+ (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
+ o1++, i1 += s1)
+ for (o0 = r->dim[0].lower_bound, i0 = lb0;
+ (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
+ o0++, i0 += s0)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = i0;
+ index[1] = i1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o0;
+ index[1] = o1;
+ output = (struct m *) CFI_address (r, index);
+ fprintf (stderr, "a(%d,%d) = (%d,%d), r(%d,%d) = (%d,%d)\n",
+ i0, i1, input->x, input->y, o0, o1, output->x, output->y);
+ }
+#endif
+ for (o1 = r->dim[1].lower_bound, i1 = lb1;
+ (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
+ o1++, i1 += s1)
+ for (o0 = r->dim[0].lower_bound, i0 = lb0;
+ (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
+ o0++, i0 += s0)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = i0;
+ index[1] = i1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o0;
+ index[1] = o1;
+ output = (struct m *) CFI_address (r, index);
+ if (input->x != output->x || input->y != output->y)
+ abort ();
+ }
+
+ /* Force the output array to be 1-based. */
+ lb_array[0] = 1;
+ lb_array[1] = 1;
+ check_CFI_status ("CFI_setpointer", CFI_setpointer (r, r, lb_array));
+ /* Check that the output descriptor is correct. */
+ dump_CFI_cdesc_t (r);
+ if (!r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(struct m))
+ abort ();
+ if (r->rank != 2)
+ abort ();
+ if (r->type != CFI_type_struct)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+ if (r->dim[0].lower_bound != 1)
+ abort ();
+
+ /* Check the contents of the output array again. */
+ for (o1 = r->dim[1].lower_bound, i1 = lb1;
+ (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
+ o1++, i1 += s1)
+ for (o0 = r->dim[0].lower_bound, i0 = lb0;
+ (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
+ o0++, i0 += s0)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = i0;
+ index[1] = i1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o0;
+ index[1] = o1;
+ output = (struct m *) CFI_address (r, index);
+ if (input->x != output->x || input->y != output->y)
+ abort ();
+ }
+}
+
+
+
Index: Fortran/gfortran/regression/c-interop/section-2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-2.f90
@@ -0,0 +1,102 @@
+! { dg-do run }
+! { dg-additional-sources "section-2-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests basic use of the CFI_section C library function on
+! a 2-dimensional non-pointer array.
+
+module mm
+ use ISO_C_BINDING
+ type, bind (c) :: m
+ integer(C_INT) :: x, y
+ end type
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (a, lb0, lb1, ub0, ub1, s0, s1, r) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), target :: a(:,:)
+ integer(C_INT), value :: lb0, lb1, ub0, ub1, s0, s1
+ type(m), pointer, intent(out) :: r(:,:)
+ end subroutine
+
+ end interface
+
+ type(m), target :: aa(10, 20)
+ integer :: i0, i1
+
+ ! Initialize the test array by numbering its elements.
+ do i1 = 1, 20
+ do i0 = 1, 10
+ aa(i0, i1)%x = i0
+ aa(i0, i1)%y = i1
+ end do
+ end do
+
+ call test (aa, 4, 3, 10, 15, 2, 3) ! basic test
+ call test (aa, 10, 15, 4, 3, -2, -3) ! negative step
+ stop
+
+contains
+
+ ! Test function for non-pointer array AA.
+ ! LB, UB, and S describe the section to take.
+ subroutine test (aa, lb0, lb1, ub0, ub1, s0, s1)
+ use mm
+ type(m) :: aa(10,20)
+ integer :: lb0, lb1, ub0, ub1, s0, s1
+
+ type(m), pointer :: rr(:,:)
+ integer :: i0, i1, o0, o1
+ integer, parameter :: hi0 = 10
+ integer, parameter :: hi1 = 20
+
+ ! Make sure the original array is OK.
+ do i1 = 1, hi1
+ do i0 = 1, hi0
+ if (aa(i0,i1)%x .ne. i0) stop 101
+ if (aa(i0,i1)%y .ne. i1) stop 101
+ end do
+ end do
+
+ ! Call the C function to put a section in rr.
+ ! The C function expects the section bounds to be 1-based.
+ nullify (rr)
+ call ctest (aa, lb0, lb1, ub0, ub1, s0, s1, rr)
+
+ ! Make sure the original array has not been modified.
+ do i1 = 1, hi1
+ do i0 = 1, hi0
+ if (aa(i0,i1)%x .ne. i0) stop 103
+ if (aa(i0,i1)%y .ne. i1) stop 103
+ end do
+ end do
+
+ ! Make sure the output array has the expected bounds and elements.
+ if (.not. associated (rr)) stop 111
+ if (lbound (rr, 1) .ne. 1) stop 112
+ if (lbound (rr, 2) .ne. 1) stop 112
+ if (ubound (rr, 1) .ne. (ub0 - lb0)/s0 + 1) stop 113
+ if (ubound (rr, 2) .ne. (ub1 - lb1)/s1 + 1) stop 113
+ o1 = 1
+ do i1 = lb1, ub1, s1
+ o0 = 1
+ do i0 = lb0, ub0, s0
+ ! print 999, o0, o1, rr(o0,o1)%x, rr(o0,01)%y
+ ! 999 format ('rr(', i3, ',', i3, ') = (', i3, ',', i3, ')')
+ if (rr(o0,o1)%x .ne. i0) stop 114
+ if (rr(o0,o1)%y .ne. i1) stop 114
+ o0 = o0 + 1
+ end do
+ o1 = o1 + 1
+ end do
+ end subroutine
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/section-2p.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-2p.f90
@@ -0,0 +1,104 @@
+! PR 101310
+! { dg-do run }
+! { dg-additional-sources "section-2-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests basic use of the CFI_section C library function on
+! a 2-dimensional pointer array.
+
+module mm
+ use ISO_C_BINDING
+ type, bind (c) :: m
+ integer(C_INT) :: x, y
+ end type
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (p, lb0, lb1, ub0, ub1, s0, s1, r) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), pointer :: p(:,:)
+ integer(C_INT), value :: lb0, lb1, ub0, ub1, s0, s1
+ type(m), pointer, intent(out) :: r(:,:)
+ end subroutine
+
+ end interface
+
+ type(m), target :: aa(10, 20)
+ integer :: i0, i1
+
+ ! Initialize the test array by numbering its elements.
+ do i1 = 1, 20
+ do i0 = 1, 10
+ aa(i0, i1)%x = i0
+ aa(i0, i1)%y = i1
+ end do
+ end do
+
+ call test (aa, 0, 0, 3, 2, 9, 14, 2, 3) ! zero lower bound
+ call test (aa, 1, 1, 4, 3, 10, 15, 2, 3) ! lower bound 1
+ call test (aa, 6, 11, 9, 13, 15, 25, 2, 3) ! other lower bound
+ call test (aa, 1, 1, 10, 15, 4, 3, -2, -3) ! negative step
+ stop
+
+contains
+
+ ! Test function for pointer array AA.
+ ! The bounds of the array are adjusted so it is based at (LO0,LO1).
+ ! LB, UB, and S describe the section of the adjusted array to take.
+ subroutine test (aa, lo0, lo1, lb0, lb1, ub0, ub1, s0, s1)
+ use mm
+ type(m), target :: aa(1:10, 1:20)
+ integer :: lo0, lo1, lb0, lb1, ub0, ub1, s0, s1
+
+ type(m), pointer :: pp(:,:), rr(:,:)
+ integer :: i0, i1, o0, o1
+ integer :: hi0, hi1
+ hi0 = lo0 + 10 - 1
+ hi1 = lo1 + 20 - 1
+
+ pp(lo0:,lo1:) => aa
+ if (lbound (pp, 1) .ne. lo0) stop 121
+ if (lbound (pp, 2) .ne. lo1) stop 121
+ if (ubound (pp, 1) .ne. hi0) stop 122
+ if (ubound (pp, 2) .ne. hi1) stop 122
+ nullify (rr)
+ call ctest (pp, lb0, lb1, ub0, ub1, s0, s1, rr)
+
+ ! Make sure the input pointer array has not been modified.
+ if (lbound (pp, 1) .ne. lo0) stop 131
+ if (ubound (pp, 1) .ne. hi0) stop 132
+ if (lbound (pp, 2) .ne. lo1) stop 133
+ if (ubound (pp, 2) .ne. hi1) stop 134
+ do i1 = lo1, hi1
+ do i0 = lo0, hi0
+ if (pp(i0,i1)%x .ne. i0 - lo0 + 1) stop 135
+ if (pp(i0,i1)%y .ne. i1 - lo1 + 1) stop 136
+ end do
+ end do
+
+ ! Make sure the output array has the expected bounds and elements.
+ if (.not. associated (rr)) stop 141
+ if (lbound (rr, 1) .ne. 1) stop 142
+ if (lbound (rr, 2) .ne. 1) stop 142
+ if (ubound (rr, 1) .ne. (ub0 - lb0)/s0 + 1) stop 143
+ if (ubound (rr, 2) .ne. (ub1 - lb1)/s1 + 1) stop 143
+ o1 = 1
+ do i1 = lb1, ub1, s1
+ o0 = 1
+ do i0 = lb0, ub0, s0
+ if (rr(o0,o1)%x .ne. i0 - lo0 + 1) stop 144
+ if (rr(o0,o1)%y .ne. i1 - lo1 + 1) stop 144
+ o0 = o0 + 1
+ end do
+ o1 = o1 + 1
+ end do
+ end subroutine
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/section-3-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-3-c.c
@@ -0,0 +1,235 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+struct m {
+ int x, y;
+};
+
+extern void ctest (CFI_cdesc_t *a, int lb0, int lb1,
+ int ub0, int ub1, int s0, int s1, CFI_cdesc_t *r);
+
+/* Take a section of array A. OFF is the start index of A on the Fortran
+ side and the bounds LB and UB for the section to take are relative to
+ that base index. Store the result in R, which is supposed to be a pointer
+ array with lower bound 1. */
+
+void
+ctest (CFI_cdesc_t *a, int lb0, int lb1,
+ int ub0, int ub1, int s0, int s1, CFI_cdesc_t *r)
+{
+ CFI_index_t lb_array[2], ub_array[2], s_array[2];
+ int i0, i1, o0, o1;
+
+ /* Dump the descriptor contents to test that we can access the fields
+ correctly, etc. */
+ fprintf (stderr, "\n%s: lb0=%d lb1=%d ub0=%d ub1=%d s0=%d s1=%d\n",
+ (a->attribute == CFI_attribute_other) ? "non-pointer" : "pointer",
+ lb0, lb1, ub0, ub1, s0, s1);
+ if (! (lb0 == ub0 || lb1 == ub1))
+ abort ();
+ dump_CFI_cdesc_t (a);
+ dump_CFI_cdesc_t (r);
+
+ /* Make sure we got a valid input descriptor. */
+ if (!a->base_addr)
+ abort ();
+ if (a->elem_len != sizeof(struct m))
+ abort ();
+ if (a->rank != 2)
+ abort ();
+ if (a->type != CFI_type_struct)
+ abort ();
+ if (a->attribute == CFI_attribute_other)
+ {
+ if (a->dim[0].lower_bound != 0)
+ abort ();
+ /* Adjust the 1-based bounds. */
+ lb0 = lb0 - 1;
+ lb1 = lb1 - 1;
+ ub0 = ub0 - 1;
+ ub1 = ub1 - 1;
+ }
+ /* For pointer arrays, the bounds use the same indexing as the lower
+ bound in the array descriptor. */
+
+ /* Make sure we got a valid output descriptor. */
+ if (r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(struct m))
+ abort ();
+ if (r->rank != 1)
+ abort ();
+ if (r->type != CFI_type_struct)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+
+ /* Create an array section. */
+ lb_array[0] = lb0;
+ lb_array[1] = lb1;
+ ub_array[0] = ub0;
+ ub_array[1] = ub1;
+ s_array[0] = s0;
+ s_array[1] = s1;
+
+ check_CFI_status ("CFI_section",
+ CFI_section (r, a, lb_array, ub_array, s_array));
+
+ /* Check that the output descriptor is correct. */
+ dump_CFI_cdesc_t (r);
+ if (!r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(struct m))
+ abort ();
+ if (r->rank != 1)
+ abort ();
+ if (r->type != CFI_type_struct)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+
+ /* Check the contents of the output array. */
+#if 0
+ if (lb1 == ub1)
+ {
+ /* Output is 1-d array that varies in dimension 0. */
+ for (o0 = r->dim[0].lower_bound, i0 = lb0;
+ (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
+ o0++, i0 += s0)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = i0;
+ index[1] = lb1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o0;
+ output = (struct m *) CFI_address (r, index);
+ fprintf (stderr, "a(%d,%d) = (%d,%d), r(%d) = (%d,%d)\n",
+ i0, lb1, input->x, input->y, o0, output->x, output->y);
+ }
+ }
+ else if (lb0 == ub0)
+ {
+ /* Output is 1-d array that varies in dimension 1. */
+ for (o1 = r->dim[0].lower_bound, i1 = lb1;
+ (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
+ o1++, i1 += s1)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = lb0;
+ index[1] = i1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o1;
+ output = (struct m *) CFI_address (r, index);
+ fprintf (stderr, "a(%d,%d) = (%d,%d), r(%d) = (%d,%d)\n",
+ lb0, i1, input->x, input->y, o1, output->x, output->y);
+ }
+ }
+ else
+ abort ();
+#endif
+ if (lb1 == ub1)
+ {
+ /* Output is 1-d array that varies in dimension 0. */
+ for (o0 = r->dim[0].lower_bound, i0 = lb0;
+ (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
+ o0++, i0 += s0)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = i0;
+ index[1] = lb1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o0;
+ output = (struct m *) CFI_address (r, index);
+ if (input->x != output->x || input->y != output->y)
+ abort ();
+ }
+ }
+ else if (lb0 == ub0)
+ {
+ /* Output is 1-d array that varies in dimension 1. */
+ for (o1 = r->dim[0].lower_bound, i1 = lb1;
+ (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
+ o1++, i1 += s1)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = lb0;
+ index[1] = i1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o1;
+ output = (struct m *) CFI_address (r, index);
+ if (input->x != output->x || input->y != output->y)
+ abort ();
+ }
+ }
+ else
+ abort ();
+
+ /* Force the output array to be 1-based. */
+ lb_array[0] = 1;
+ lb_array[1] = 1;
+ check_CFI_status ("CFI_setpointer", CFI_setpointer (r, r, lb_array));
+ /* Check that the output descriptor is correct. */
+ dump_CFI_cdesc_t (r);
+ if (!r->base_addr)
+ abort ();
+ if (r->elem_len != sizeof(struct m))
+ abort ();
+ if (r->rank != 1)
+ abort ();
+ if (r->type != CFI_type_struct)
+ abort ();
+ if (r->attribute != CFI_attribute_pointer)
+ abort ();
+ if (r->dim[0].lower_bound != 1)
+ abort ();
+
+ /* Check the contents of the output array again. */
+ if (lb1 == ub1)
+ {
+ /* Output is 1-d array that varies in dimension 0. */
+ for (o0 = r->dim[0].lower_bound, i0 = lb0;
+ (s0 > 0 ? i0 <= ub0 : i0 >= ub0);
+ o0++, i0 += s0)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = i0;
+ index[1] = lb1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o0;
+ output = (struct m *) CFI_address (r, index);
+ if (input->x != output->x || input->y != output->y)
+ abort ();
+ }
+ }
+ else if (lb0 == ub0)
+ {
+ /* Output is 1-d array that varies in dimension 1. */
+ for (o1 = r->dim[0].lower_bound, i1 = lb1;
+ (s1 > 0 ? i1 <= ub1 : i1 >= ub1);
+ o1++, i1 += s1)
+ {
+ CFI_index_t index[2];
+ struct m *input, *output;
+ index[0] = lb0;
+ index[1] = i1;
+ input = (struct m *) CFI_address (a, index);
+ index[0] = o1;
+ output = (struct m *) CFI_address (r, index);
+ if (input->x != output->x || input->y != output->y)
+ abort ();
+ }
+ }
+ else
+ abort ();
+}
+
+
+
Index: Fortran/gfortran/regression/c-interop/section-3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-3.f90
@@ -0,0 +1,103 @@
+! PR 101310
+! { dg-do run }
+! { dg-additional-sources "section-3-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests basic use of the CFI_section C library function to
+! take a slice of a 2-dimensional non-pointer array.
+
+module mm
+ use ISO_C_BINDING
+ type, bind (c) :: m
+ integer(C_INT) :: x, y
+ end type
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (a, lb0, lb1, ub0, ub1, s0, s1, r) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), target :: a(:,:)
+ integer(C_INT), value :: lb0, lb1, ub0, ub1, s0, s1
+ type(m), pointer, intent(out) :: r(:)
+ end subroutine
+
+ end interface
+
+ type(m), target :: aa(10, 20)
+ integer :: i0, i1
+
+ ! Initialize the test array by numbering its elements.
+ do i1 = 1, 20
+ do i0 = 1, 10
+ aa(i0, i1)%x = i0
+ aa(i0, i1)%y = i1
+ end do
+ end do
+
+ call test (aa, 3, 1, 3, 20, 0, 1) ! full slice 0
+ call test (aa, 1, 8, 10, 8, 1, 0) ! full slice 1
+ call test (aa, 3, 5, 3, 14, 0, 3) ! partial slice 0
+ call test (aa, 2, 8, 10, 8, 2, 0) ! partial slice 1
+ call test (aa, 3, 14, 3, 5, 0, -3) ! backwards slice 0
+ call test (aa, 10, 8, 2, 8, -2, 0) ! backwards slice 1
+
+contains
+
+ ! Test function for non-pointer array AA.
+ ! LB, UB, and S describe the section to take.
+ subroutine test (aa, lb0, lb1, ub0, ub1, s0, s1)
+ use mm
+ type(m) :: aa(10,20)
+ integer :: lb0, lb1, ub0, ub1, s0, s1
+
+ type(m), pointer :: rr(:)
+ integer :: i0, i1, o0, o1
+ integer, parameter :: hi0 = 10
+ integer, parameter :: hi1 = 20
+
+ ! Check the bounds actually specify a "slice" rather than a subarray.
+ if (lb0 .ne. ub0 .and. lb1 .ne. ub1) stop 100
+
+ ! Call the C function to put a section in rr.
+ ! The C function expects the section bounds to be 1-based.
+ nullify (rr)
+ call ctest (aa, lb0, lb1, ub0, ub1, s0, s1, rr)
+
+ ! Make sure the original array has not been modified.
+ do i1 = 1, hi1
+ do i0 = 1, hi0
+ if (aa(i0,i1)%x .ne. i0) stop 103
+ if (aa(i0,i1)%y .ne. i1) stop 103
+ end do
+ end do
+
+ ! Make sure the output array has the expected bounds and elements.
+ if (.not. associated (rr)) stop 111
+ if (lbound (rr, 1) .ne. 1) stop 112
+ if (ub0 .eq. lb0) then
+ if (ubound (rr, 1) .ne. (ub1 - lb1)/s1 + 1) stop 113
+ o1 = 1
+ do i1 = lb1, ub1, s1
+ if (rr(o1)%x .ne. lb0) stop 114
+ if (rr(o1)%y .ne. i1) stop 114
+ o1 = o1 + 1
+ end do
+ else
+ if (ubound (rr, 1) .ne. (ub0 - lb0)/s0 + 1) stop 113
+ o0 = 1
+ do i0 = lb0, ub0, s0
+ if (rr(o0)%x .ne. i0) stop 114
+ if (rr(o0)%y .ne. lb1) stop 114
+ o0 = o0 + 1
+ end do
+ end if
+ end subroutine
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/section-3p.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-3p.f90
@@ -0,0 +1,127 @@
+! PR 101310
+! { dg-do run }
+! { dg-additional-sources "section-3-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests basic use of the CFI_section C library function to
+! take a slice of a 2-dimensional pointer array.
+
+module mm
+ use ISO_C_BINDING
+ type, bind (c) :: m
+ integer(C_INT) :: x, y
+ end type
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+ subroutine ctest (p, lb0, lb1, ub0, ub1, s0, s1, r) bind (c)
+ use iso_c_binding
+ use mm
+ type(m), pointer :: p(:,:)
+ integer(C_INT), value :: lb0, lb1, ub0, ub1, s0, s1
+ type(m), pointer, intent(out) :: r(:)
+ end subroutine
+
+ end interface
+
+ type(m), target :: aa(10, 20)
+ integer :: i0, i1
+
+ ! Initialize the test array by numbering its elements.
+ do i1 = 1, 20
+ do i0 = 1, 10
+ aa(i0, i1)%x = i0
+ aa(i0, i1)%y = i1
+ end do
+ end do
+
+ ! Zero lower bound
+ call test (aa, 0, 0, 2, 0, 2, 19, 0, 1) ! full slice 0
+ call test (aa, 0, 0, 0, 7, 9, 7, 1, 0) ! full slice 1
+ call test (aa, 0, 0, 2, 4, 2, 13, 0, 3) ! partial slice 0
+ call test (aa, 0, 0, 1, 7, 9, 7, 2, 0) ! partial slice 1
+ call test (aa, 0, 0, 2, 13, 2, 4, 0, -3) ! backwards slice 0
+ call test (aa, 0, 0, 9, 7, 1, 7, -2, 0) ! backwards slice 1
+
+ ! Lower bound 1
+ call test (aa, 1, 1, 3, 1, 3, 20, 0, 1) ! full slice 0
+ call test (aa, 1, 1, 1, 8, 10, 8, 1, 0) ! full slice 1
+ call test (aa, 1, 1, 3, 5, 3, 14, 0, 3) ! partial slice 0
+ call test (aa, 1, 1, 2, 8, 10, 8, 2, 0) ! partial slice 1
+ call test (aa, 1, 1, 3, 14, 3, 5, 0, -3) ! backwards slice 0
+ call test (aa, 1, 1, 10, 8, 2, 8, -2, 0) ! backwards slice 1
+
+ ! Some other lower bound
+ call test (aa, 2, 3, 4, 3, 4, 22, 0, 1) ! full slice 0
+ call test (aa, 2, 3, 2, 10, 11, 10, 1, 0) ! full slice 1
+ call test (aa, 2, 3, 4, 7, 4, 16, 0, 3) ! partial slice 0
+ call test (aa, 2, 3, 3, 10, 11, 10, 2, 0) ! partial slice 1
+ call test (aa, 2, 3, 4, 16, 4, 7, 0, -3) ! backwards slice 0
+ call test (aa, 2, 3, 11, 10, 3, 10, -2, 0) ! backwards slice 1
+
+contains
+
+ subroutine test (aa, lo0, lo1, lb0, lb1, ub0, ub1, s0, s1)
+ use mm
+ type(m), target :: aa(10,20)
+ integer :: lo0, lo1, lb0, lb1, ub0, ub1, s0, s1
+
+ type(m), pointer :: pp(:,:), rr(:)
+ integer :: i0, i1, o0, o1
+
+ integer :: hi0, hi1
+ hi0 = lo0 + 10 - 1
+ hi1 = lo1 + 20 - 1
+
+ ! Check the bounds actually specify a "slice" rather than a subarray.
+ if (lb0 .ne. ub0 .and. lb1 .ne. ub1) stop 100
+
+ pp(lo0:,lo1:) => aa
+ if (lbound (pp, 1) .ne. lo0) stop 121
+ if (lbound (pp, 2) .ne. lo1) stop 121
+ if (ubound (pp, 1) .ne. hi0) stop 122
+ if (ubound (pp, 2) .ne. hi1) stop 122
+ nullify (rr)
+ call ctest (pp, lb0, lb1, ub0, ub1, s0, s1, rr)
+
+ ! Make sure the input pointer array has not been modified.
+ if (lbound (pp, 1) .ne. lo0) stop 131
+ if (ubound (pp, 1) .ne. hi0) stop 132
+ if (lbound (pp, 2) .ne. lo1) stop 133
+ if (ubound (pp, 2) .ne. hi1) stop 134
+ do i1 = lo1, hi1
+ do i0 = lo0, hi0
+ if (pp(i0,i1)%x .ne. i0 - lo0 + 1) stop 135
+ if (pp(i0,i1)%y .ne. i1 - lo1 + 1) stop 136
+ end do
+ end do
+
+ ! Make sure the output array has the expected bounds and elements.
+ if (.not. associated (rr)) stop 111
+ if (lbound (rr, 1) .ne. 1) stop 112
+ if (ub0 .eq. lb0) then
+ if (ubound (rr, 1) .ne. (ub1 - lb1)/s1 + 1) stop 113
+ o1 = 1
+ do i1 = lb1, ub1, s1
+ if (rr(o1)%x .ne. lb0 - lo0 + 1) stop 114
+ if (rr(o1)%y .ne. i1 - lo1 + 1) stop 114
+ o1 = o1 + 1
+ end do
+ else
+ if (ubound (rr, 1) .ne. (ub0 - lb0)/s0 + 1) stop 113
+ o0 = 1
+ do i0 = lb0, ub0, s0
+ if (rr(o0)%x .ne. i0 - lo0 + 1) stop 114
+ if (rr(o0)%y .ne. lb1 - lo1 + 1) stop 114
+ o0 = o0 + 1
+ end do
+ end if
+ end subroutine
+
+end program
+
Index: Fortran/gfortran/regression/c-interop/section-4-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-4-c.c
@@ -0,0 +1,101 @@
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+struct m {
+ int i, j, k, l;
+};
+
+extern void ctest (void);
+
+#define IMAX 6
+#define JMAX 8
+#define KMAX 10
+#define LMAX 12
+
+static struct m buffer[LMAX][KMAX][JMAX][IMAX];
+
+static void
+check_element (struct m *mp, int i, int j, int k, int l)
+{
+#if 0
+ fprintf (stderr, "expected (%d, %d, %d, %d), got (%d, %d, %d, %d)\n",
+ i, j, k, l, mp->i, mp->j, mp->k, mp->l);
+#endif
+ if (mp->i != i || mp->j != j || mp->k != k || mp->l != l)
+ abort ();
+}
+
+void
+ctest (void)
+{
+ CFI_CDESC_T(4) sdesc;
+ CFI_cdesc_t *source = (CFI_cdesc_t *) &sdesc;
+ CFI_CDESC_T(4) rdesc;
+ CFI_cdesc_t *result = (CFI_cdesc_t *) &rdesc;
+ CFI_index_t extents[4] = { IMAX, JMAX, KMAX, LMAX };
+ CFI_index_t lb[4], ub[4], s[4];
+ int i, j, k, l;
+ int ii, jj, kk, ll;
+
+ /* Initialize the buffer to uniquely label each element. */
+ for (i = 0; i < IMAX; i++)
+ for (j = 0; j < JMAX; j++)
+ for (k = 0; k < KMAX; k++)
+ for (l = 0; l < LMAX; l++)
+ {
+ buffer[l][k][j][i].i = i;
+ buffer[l][k][j][i].j = j;
+ buffer[l][k][j][i].k = k;
+ buffer[l][k][j][i].l = l;
+ }
+
+ /* Establish the source array. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)buffer,
+ CFI_attribute_pointer, CFI_type_struct,
+ sizeof (struct m), 4, extents));
+
+ /* Try taking a degenerate section (single element). */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL,
+ CFI_attribute_pointer, CFI_type_struct,
+ sizeof (struct m), 0, NULL));
+ lb[0] = 3; lb[1] = 4; lb[2] = 5; lb[3] = 6;
+ ub[0] = 3; ub[1] = 4; ub[2] = 5; ub[3] = 6;
+ s[0] = 0; s[1] = 0; s[2] = 0; s[3] = 0;
+ check_CFI_status ("CFI_section",
+ CFI_section (result, source, lb, ub, s));
+ dump_CFI_cdesc_t (result);
+ check_element ((struct m *)result->base_addr, 3, 4, 5, 6);
+
+ /* Try taking a 2d chunk out of the 4d array. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL,
+ CFI_attribute_pointer, CFI_type_struct,
+ sizeof (struct m), 2, NULL));
+ lb[0] = 1; lb[1] = 2; lb[2] = 3; lb[3] = 4;
+ ub[0] = 1; ub[1] = JMAX - 2; ub[2] = 3; ub[3] = LMAX - 2;
+ s[0] = 0; s[1] = 2; s[2] = 0; s[3] = 3;
+ check_CFI_status ("CFI_section",
+ CFI_section (result, source, lb, ub, s));
+ dump_CFI_cdesc_t (result);
+
+ i = lb[0];
+ k = lb[2];
+ for (j = lb[1], jj = result->dim[0].lower_bound;
+ j <= ub[1];
+ j += s[1], jj++)
+ for (l = lb[3], ll = result->dim[1].lower_bound;
+ l <= ub[3];
+ l += s[3], ll++)
+ {
+ CFI_index_t subscripts[2];
+ subscripts[0] = jj;
+ subscripts[1] = ll;
+ check_element ((struct m *) CFI_address (result, subscripts),
+ i, j, k, l);
+ }
+}
Index: Fortran/gfortran/regression/c-interop/section-4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-4.f90
@@ -0,0 +1,23 @@
+! PR 101310
+! { dg-do run }
+! { dg-additional-sources "section-4-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests various scenarios with using CFI_section to extract
+! a section with rank less than the source array. Everything interesting
+! happens on the C side.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest () bind (c)
+ use iso_c_binding
+ end subroutine
+
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/section-errors-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-errors-c.c
@@ -0,0 +1,149 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+/* For simplicity, point descriptors at a static buffer. */
+#define BUFSIZE 256
+static char *buf[BUFSIZE] __attribute__ ((aligned (8)));
+static CFI_index_t extents[] = {10};
+
+/* External entry point. The arguments are descriptors for input arrays;
+ we'll construct new descriptors for the outputs of CFI_section. */
+extern void ctest (void);
+
+void
+ctest (void)
+{
+ int bad = 0;
+ int status;
+ CFI_CDESC_T(1) sdesc;
+ CFI_cdesc_t *source = (CFI_cdesc_t *) &sdesc;
+ CFI_CDESC_T(3) rdesc;
+ CFI_cdesc_t *result = (CFI_cdesc_t *) &rdesc;
+ CFI_index_t lb = 2;
+ CFI_index_t ub = 8;
+ CFI_index_t step = 2;
+ CFI_index_t zstep = 0;
+
+ /* Use a 1-d integer source array for the first few tests. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)buf, CFI_attribute_other,
+ CFI_type_int, 0, 1, extents));
+
+ /* result shall be the address of a C descriptor with rank equal
+ to the rank of source minus the number of zero strides. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 0, NULL));
+ status = CFI_section (result, source, &lb, &ub, &step);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for rank mismatch (too small)\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 1, NULL));
+ status = CFI_section (result, source, &lb, &lb, &zstep);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for rank mismatch (zero stride)\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 3, NULL));
+ status = CFI_section (result, source, &lb, &ub, &step);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for rank mismatch (too large)\n");
+ bad ++;
+ }
+
+ /* The attribute member [of result] shall have the value
+ CFI_attribute_other or CFI_attribute_pointer. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_allocatable,
+ CFI_type_int, 0, 1, NULL));
+ status = CFI_section (result, source, &lb, &ub, &step);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for CFI_attribute_allocatable result\n");
+ bad ++;
+ }
+
+ /* source shall be the address of a C descriptor that describes a
+ nonallocatable nonpointer array, an allocated allocatable array,
+ or an associated array pointer. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, NULL, CFI_attribute_allocatable,
+ CFI_type_int, 0, 1, NULL));
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 1, NULL));
+ status = CFI_section (result, source, &lb, &ub, &step);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for unallocated allocatable source array\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 1, NULL));
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 1, NULL));
+ status = CFI_section (result, source, &lb, &ub, &step);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for unassociated pointer source array\n");
+ bad ++;
+ }
+
+ /* The corresponding values of the elem_len and type members shall
+ be the same in the C descriptors with the addresses source
+ and result. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)buf, CFI_attribute_other,
+ CFI_type_struct,
+ sizeof(int), 1, extents));
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_struct,
+ 2*sizeof (int), 1, NULL));
+ status = CFI_section (result, source, &lb, &ub, &step);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for elem_len mismatch\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 1, NULL));
+ status = CFI_section (result, source, &lb, &ub, &step);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for type mismatch\n");
+ bad ++;
+ }
+
+ if (bad)
+ abort ();
+}
+
Index: Fortran/gfortran/regression/c-interop/section-errors.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/section-errors.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+! { dg-additional-sources "section-errors-c.c dump-descriptors.c" }
+! { dg-additional-options "-Wno-error -fcheck=all" }
+! { dg-warning "command-line option '-fcheck=all' is valid for Fortran but not for C" "" { target *-*-* } 0 }
+!
+! This program tests that the CFI_section function properly detects
+! invalid arguments. All the interesting things happen in the
+! corresponding C code.
+!
+! The situation here seems to be that while TS29113 defines error codes
+! for CFI_section, it doesn't actually require the implementation to detect
+! those errors by saying the arguments "shall be" such-and-such, e.g. it is
+! undefined behavior if they are not. In gfortran you can enable some
+! run-time checking by building with -fcheck=all.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest () bind (c)
+ end subroutine
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/select-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/select-c.c
@@ -0,0 +1,138 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+/* Declare some source arrays. */
+struct ss {
+ char c[4];
+ signed char b[4];
+ int i, j, k;
+} s[10][5][3];
+
+char c[10][16];
+
+double _Complex dc[10];
+
+CFI_index_t extents3[] = {3,5,10};
+CFI_index_t extents1[] = {10};
+
+/* External entry point. */
+extern void ctest (void);
+
+void
+ctest (void)
+{
+ CFI_CDESC_T(3) sdesc;
+ CFI_cdesc_t *source = (CFI_cdesc_t *) &sdesc;
+ CFI_CDESC_T(3) rdesc;
+ CFI_cdesc_t *result = (CFI_cdesc_t *) &rdesc;
+ size_t offset;
+
+ /* Extract an array of structure elements. */
+ offset = offsetof (struct ss, j);
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)s, CFI_attribute_other,
+ CFI_type_struct,
+ sizeof (struct ss), 3, extents3));
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 3, NULL));
+ check_CFI_status ("CFI_select_part",
+ CFI_select_part (result, source, offset, 0));
+ dump_CFI_cdesc_t (source);
+ dump_CFI_cdesc_t (result);
+
+ if (result->elem_len != sizeof (int))
+ abort ();
+ if (result->base_addr != source->base_addr + offset)
+ abort ();
+ if (result->dim[0].extent != source->dim[0].extent)
+ abort ();
+ if (result->dim[0].sm != source->dim[0].sm)
+ abort ();
+ if (result->dim[1].extent != source->dim[1].extent)
+ abort ();
+ if (result->dim[1].sm != source->dim[1].sm)
+ abort ();
+ if (result->dim[2].extent != source->dim[2].extent)
+ abort ();
+ if (result->dim[2].sm != source->dim[2].sm)
+ abort ();
+
+ /* Check that we use the given elem_size for char but not for
+ signed char, which is considered an integer type instead of a Fortran
+ character type. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_char, 4, 3, NULL));
+ if (result->elem_len != 4)
+ abort ();
+ offset = offsetof (struct ss, c);
+ check_CFI_status ("CFI_select_part",
+ CFI_select_part (result, source, offset, 4));
+ if (result->elem_len != 4)
+ abort ();
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_signed_char, 4, 3, NULL));
+ if (result->elem_len != sizeof (signed char))
+ abort ();
+ offset = offsetof (struct ss, c);
+ check_CFI_status ("CFI_select_part",
+ CFI_select_part (result, source, offset, 4));
+ if (result->elem_len != sizeof (signed char))
+ abort ();
+
+ /* Extract an array of character substrings. */
+ offset = 2;
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)c, CFI_attribute_other,
+ CFI_type_char, 16, 1, extents1));
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_char, 8, 1, NULL));
+ check_CFI_status ("CFI_select_part",
+ CFI_select_part (result, source, offset, 8));
+ dump_CFI_cdesc_t (source);
+ dump_CFI_cdesc_t (result);
+
+ if (result->elem_len != 8)
+ abort ();
+ if (result->base_addr != source->base_addr + offset)
+ abort ();
+ if (result->dim[0].extent != source->dim[0].extent)
+ abort ();
+ if (result->dim[0].sm != source->dim[0].sm)
+ abort ();
+
+ /* Extract an array the imaginary parts of complex numbers.
+ Note that the use of __imag__ to obtain the imaginary part as
+ an lvalue is a GCC extension. */
+ offset = (void *)&(__imag__ dc[0]) - (void *)&(dc[0]);
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)dc, CFI_attribute_other,
+ CFI_type_double_Complex,
+ 0, 1, extents1));
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_double, 0, 1, NULL));
+ check_CFI_status ("CFI_select_part",
+ CFI_select_part (result, source, offset, 0));
+ dump_CFI_cdesc_t (source);
+ dump_CFI_cdesc_t (result);
+
+ if (result->elem_len != sizeof (double))
+ abort ();
+ if (result->base_addr != source->base_addr + offset)
+ abort ();
+ if (result->dim[0].extent != source->dim[0].extent)
+ abort ();
+ if (result->dim[0].sm != source->dim[0].sm)
+ abort ();
+}
+
Index: Fortran/gfortran/regression/c-interop/select-errors-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/select-errors-c.c
@@ -0,0 +1,125 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+/* Source is an array of structs. */
+struct ss {
+ int i, j;
+ char c[16];
+ double _Complex dc;
+} s[10];
+
+CFI_index_t extents[] = {10};
+
+/* External entry point. */
+extern void ctest (void);
+
+void
+ctest (void)
+{
+ int bad = 0;
+ int status;
+ CFI_CDESC_T(1) sdesc;
+ CFI_cdesc_t *source = (CFI_cdesc_t *) &sdesc;
+ CFI_CDESC_T(3) rdesc;
+ CFI_cdesc_t *result = (CFI_cdesc_t *) &rdesc;
+
+ /* Create a descriptor for the source array. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)s, CFI_attribute_other,
+ CFI_type_struct,
+ sizeof (struct ss), 1, extents));
+
+ /* The attribute member of result shall have the value
+ CFI_attribute_other or CFI_attribute_pointer. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_allocatable,
+ CFI_type_int, 0, 1, NULL));
+ status = CFI_select_part (result, source, offsetof (struct ss, j), 0);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for CFI_attribute_allocatable result\n");
+ bad ++;
+ }
+
+ /* The rank member of the result C descriptor shall have the same value
+ as the rank member of the C descriptor at the address specified
+ by source. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 0, NULL));
+ status = CFI_select_part (result, source, offsetof (struct ss, j), 0);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for rank mismatch (too small)\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 3, NULL));
+ status = CFI_select_part (result, source, offsetof (struct ss, j), 0);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for rank mismatch (too large)\n");
+ bad ++;
+ }
+
+ /* The value of displacement shall be between 0 and source->elem_len - 1
+ inclusive. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 1, NULL));
+ status = CFI_select_part (result, source, -8, 0);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for negative displacement\n");
+ bad ++;
+ }
+ status = CFI_select_part (result, source, source->elem_len, 0);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for too-large displacement\n");
+ bad ++;
+ }
+
+ /* source shall be the address of a C descriptor for a nonallocatable
+ nonpointer array, an allocated allocatable array, or an associated
+ array pointer. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, NULL, CFI_attribute_allocatable,
+ CFI_type_struct,
+ sizeof (struct ss), 1, NULL));
+ status = CFI_select_part (result, source, offsetof (struct ss, j), 0);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for unallocated allocatable source array\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, NULL, CFI_attribute_pointer,
+ CFI_type_struct,
+ sizeof (struct ss), 1, NULL));
+ status = CFI_select_part (result, source, offsetof (struct ss, j), 0);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for unassociated pointer source array\n");
+ bad ++;
+ }
+
+ if (bad)
+ abort ();
+}
+
Index: Fortran/gfortran/regression/c-interop/select-errors.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/select-errors.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+! { dg-additional-sources "select-errors-c.c dump-descriptors.c" }
+! { dg-additional-options "-Wno-error -fcheck=all" }
+! { dg-warning "command-line option '-fcheck=all' is valid for Fortran but not for C" "" { target *-*-* } 0 }
+!
+! This program tests that the CFI_select_part function properly detects
+! invalid arguments. All the interesting things happen in the
+! corresponding C code.
+!
+! The situation here seems to be that while TS29113 defines error codes for
+! CFI_select_part, it doesn't actually require the implementation to detect
+! those errors by saying the arguments "shall be" such-and-such, e.g. it is
+! undefined behavior if they are not. In gfortran you can enable some
+! run-time checking by building with -fcheck=all.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest () bind (c)
+ end subroutine
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/select.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/select.f90
@@ -0,0 +1,18 @@
+! { dg-do run }
+! { dg-additional-sources "select-c.c dump-descriptors.c" }
+!
+! This program tests the CFI_select_part function. All the interesting
+! things happen in the corresponding C code.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest () bind (c)
+ end subroutine
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/setpointer-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/setpointer-c.c
@@ -0,0 +1,78 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+static int a[10][5][3];
+static CFI_index_t extents[] = {3, 5, 10};
+static CFI_index_t lb1[] = {1, 2, 3};
+static CFI_index_t lb2[] = {0, 1, -10};
+
+/* External entry point. */
+extern void ctest (void);
+
+void
+ctest (void)
+{
+ CFI_CDESC_T(3) sdesc;
+ CFI_cdesc_t *source = (CFI_cdesc_t *) &sdesc;
+ CFI_CDESC_T(3) rdesc;
+ CFI_cdesc_t *result = (CFI_cdesc_t *) &rdesc;
+
+ /* Create descriptors. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)a, CFI_attribute_pointer,
+ CFI_type_int, 0, 3, extents));
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 3, NULL));
+
+ /* Use setpointer to adjust the bounds of source in place. */
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (source, source, lb1));
+ dump_CFI_cdesc_t (source);
+ if (source->dim[0].lower_bound != lb1[0])
+ abort ();
+ if (source->dim[1].lower_bound != lb1[1])
+ abort ();
+ if (source->dim[2].lower_bound != lb1[2])
+ abort ();
+
+ /* Use setpointer to copy the pointer and bounds from source. */
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (result, source, NULL));
+ dump_CFI_cdesc_t (result);
+ if (result->base_addr != source->base_addr)
+ abort ();
+ if (result->dim[0].lower_bound != source->dim[0].lower_bound)
+ abort ();
+ if (result->dim[1].lower_bound != source->dim[1].lower_bound)
+ abort ();
+ if (result->dim[2].lower_bound != source->dim[2].lower_bound)
+ abort ();
+
+ /* Use setpointer to nullify result. */
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (result, NULL, NULL));
+ dump_CFI_cdesc_t (result);
+ if (result->base_addr)
+ abort ();
+
+ /* Use setpointer to copy the pointer from source, but use
+ different bounds. */
+ check_CFI_status ("CFI_setpointer",
+ CFI_setpointer (result, source, lb2));
+ dump_CFI_cdesc_t (source);
+ if (result->base_addr != source->base_addr)
+ abort ();
+ if (result->dim[0].lower_bound != lb2[0])
+ abort ();
+ if (result->dim[1].lower_bound != lb2[1])
+ abort ();
+ if (result->dim[2].lower_bound != lb2[2])
+ abort ();
+}
+
Index: Fortran/gfortran/regression/c-interop/setpointer-errors-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/setpointer-errors-c.c
@@ -0,0 +1,127 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+static int a[10][5][3];
+static CFI_index_t extents[] = {3, 5, 10};
+
+/* External entry point. */
+extern void ctest (void);
+
+void
+ctest (void)
+{
+ int bad = 0;
+ int status;
+ CFI_CDESC_T(3) sdesc;
+ CFI_cdesc_t *source = (CFI_cdesc_t *) &sdesc;
+ CFI_CDESC_T(3) rdesc;
+ CFI_cdesc_t *result = (CFI_cdesc_t *) &rdesc;
+
+ /* result shall be the address of a C descriptor for a Fortran pointer. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)a, CFI_attribute_other,
+ CFI_type_int, 0, 3, extents));
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_allocatable,
+ CFI_type_int, 0, 3, NULL));
+ status = CFI_setpointer (result, source, NULL);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for CFI_attribute_allocatable result\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_other,
+ CFI_type_int, 0, 3, NULL));
+ status = CFI_setpointer (result, source, NULL);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for CFI_attribute_other result\n");
+ bad ++;
+ }
+
+ /* source shall be a null pointer or the address of a C descriptor
+ for an allocated allocatable object, a data pointer object, or a
+ nonallocatable nonpointer data object that is not an
+ assumed-size array. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 3, NULL));
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, NULL, CFI_attribute_allocatable,
+ CFI_type_int, 0, 3, NULL));
+ status = CFI_setpointer (result, source, NULL);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for unallocated allocatable source\n");
+ bad ++;
+ }
+
+ /* CFI_establish rejects negative extents, so we can't use it to make
+ an assumed-size array, so hack the descriptor by hand. Yuck. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)a, CFI_attribute_other,
+ CFI_type_int, 0, 3, extents));
+ source->dim[2].extent = -1;
+ status = CFI_setpointer (result, source, NULL);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for assumed-size source array\n");
+ bad ++;
+ }
+
+ /* If source is not a null pointer, the corresponding values of the
+ elem_len, rank, and type members shall be the same in the C
+ descriptors with the addresses source and result. */
+ check_CFI_status ("CFI_establish",
+ CFI_establish (source, (void *)a, CFI_attribute_other,
+ CFI_type_char, sizeof(int), 3, extents));
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_char, 1, 3, NULL));
+ status = CFI_setpointer (result, source, NULL);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for elem_len mismatch\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_char, sizeof(int), 1, NULL));
+ status = CFI_setpointer (result, source, NULL);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for rank mismatch\n");
+ bad ++;
+ }
+
+ check_CFI_status ("CFI_establish",
+ CFI_establish (result, NULL, CFI_attribute_pointer,
+ CFI_type_int, 0, 3, NULL));
+ status = CFI_setpointer (result, source, NULL);
+ if (status == CFI_SUCCESS)
+ {
+ fprintf (stderr,
+ "no error for type mismatch\n");
+ bad ++;
+ }
+
+ if (bad)
+ abort ();
+}
+
Index: Fortran/gfortran/regression/c-interop/setpointer-errors.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/setpointer-errors.f90
@@ -0,0 +1,28 @@
+! PR 101317
+! { dg-do run }
+! { dg-additional-sources "setpointer-errors-c.c dump-descriptors.c" }
+! { dg-additional-options "-Wno-error -fcheck=all" }
+! { dg-warning "command-line option '-fcheck=all' is valid for Fortran but not for C" "" { target *-*-* } 0 }
+!
+! This program tests that the CFI_setpointer function properly detects
+! invalid arguments. All the interesting things happen in the
+! corresponding C code.
+!
+! The situation here seems to be that while TS29113 defines error codes for
+! CFI_setpointer, it doesn't actually require the implementation to detect
+! those errors by saying the arguments "shall be" such-and-such, e.g. it is
+! undefined behavior if they are not. In gfortran you can enable some
+! run-time checking by building with -fcheck=all.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest () bind (c)
+ end subroutine
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/setpointer.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/setpointer.f90
@@ -0,0 +1,18 @@
+! { dg-do run }
+! { dg-additional-sources "setpointer-c.c dump-descriptors.c" }
+!
+! This program tests the CFI_setpointer function. All the interesting
+! things happen in the corresponding C code.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+ subroutine ctest () bind (c)
+ end subroutine
+ end interface
+
+ call ctest ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/shape-bindc.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/shape-bindc.f90
@@ -0,0 +1,77 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.4.1 SHAPE
+!
+! The description of the intrinsic function SHAPE in ISO/IEC 1539-1:2010
+! is changed for an assumed-rank array that is associated with an
+! assumed-size array; an assumed-size array has no shape, but in this
+! case the result has a value equal to
+! [ (SIZE (ARRAY, I, KIND), I=1,RANK (ARRAY)) ]
+! with KIND omitted from SIZE if it was omitted from SHAPE.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+
+program test
+
+ ! Define some arrays for testing.
+ integer, target :: x1(5)
+ integer :: y1(0:9)
+ integer, pointer :: p1(:)
+ integer, allocatable :: a1(:)
+ integer, target :: x3(2,3,4)
+ integer :: y3(0:1,-3:-1,4)
+ integer, pointer :: p3(:,:,:)
+ integer, allocatable :: a3(:,:,:)
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call test1 (y1)
+ p1 => x1
+ call test1 (p1)
+ allocate (a1(5))
+ call test1 (a1)
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+contains
+
+ subroutine testit (a) bind(c)
+ integer :: a(..)
+
+ integer :: r
+ r = rank(a)
+
+ block
+ integer :: s(r)
+ s = shape(a)
+ do i = 1, r
+ if (s(i) .ne. size(a,i)) stop 101
+ end do
+ end block
+
+ end subroutine
+
+ subroutine test1 (a) bind(c)
+ integer :: a(*)
+
+ call testit (a)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2) bind(c)
+ implicit none
+ integer :: l1, u1, l2, u2
+ integer :: a(l1:u1, l2:u2, *)
+
+ call testit (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/shape-poly.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/shape-poly.f90
@@ -0,0 +1,89 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.4.1 SHAPE
+!
+! The description of the intrinsic function SHAPE in ISO/IEC 1539-1:2010
+! is changed for an assumed-rank array that is associated with an
+! assumed-size array; an assumed-size array has no shape, but in this
+! case the result has a value equal to
+! [ (SIZE (ARRAY, I, KIND), I=1,RANK (ARRAY)) ]
+! with KIND omitted from SIZE if it was omitted from SHAPE.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+!
+! This is the polymorphic version of shape.f90.
+
+module m
+ type :: t
+ integer :: id
+ real :: xyz(3)
+ end type
+end module
+
+program test
+ use m
+
+ ! Define some arrays for testing.
+ type(t), target :: x1(5)
+ type(t) :: y1(0:9)
+ class(t), pointer :: p1(:)
+ class(t), allocatable :: a1(:)
+ type(t), target :: x3(2,3,4)
+ type(t) :: y3(0:1,-3:-1,4)
+ class(t), pointer :: p3(:,:,:)
+ type(t), allocatable :: a3(:,:,:)
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call test1 (y1)
+ p1 => x1
+ call test1 (p1)
+ allocate (a1(5))
+ call test1 (a1)
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+contains
+
+ subroutine testit (a)
+ use m
+ class(t) :: a(..)
+
+ integer :: r
+ r = rank(a)
+
+ block
+ integer :: s(r)
+ s = shape(a)
+ do i = 1, r
+ if (s(i) .ne. size(a,i)) stop 101
+ end do
+ end block
+
+ end subroutine
+
+ subroutine test1 (a)
+ use m
+ class(t) :: a(*)
+
+ call testit (a)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2)
+ use m
+ integer :: l1, u1, l2, u2
+ class(t) :: a(l1:u1, l2:u2, *)
+
+ call testit (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/shape.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/shape.f90
@@ -0,0 +1,77 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.4.1 SHAPE
+!
+! The description of the intrinsic function SHAPE in ISO/IEC 1539-1:2010
+! is changed for an assumed-rank array that is associated with an
+! assumed-size array; an assumed-size array has no shape, but in this
+! case the result has a value equal to
+! [ (SIZE (ARRAY, I, KIND), I=1,RANK (ARRAY)) ]
+! with KIND omitted from SIZE if it was omitted from SHAPE.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+
+program test
+ implicit none
+ ! Define some arrays for testing.
+ integer, target :: x1(5)
+ integer :: y1(0:9)
+ integer, pointer :: p1(:)
+ integer, allocatable :: a1(:)
+ integer, target :: x3(2,3,4)
+ integer :: y3(0:1,-3:-1,4)
+ integer, pointer :: p3(:,:,:)
+ integer, allocatable :: a3(:,:,:)
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call test1 (y1)
+ p1 => x1
+ call test1 (p1)
+ allocate (a1(5))
+ call test1 (a1)
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+contains
+
+ subroutine testit (a)
+ integer :: a(..)
+
+ integer :: r
+ r = rank(a)
+
+ block
+ integer :: s(r), i
+ s = shape(a)
+ do i = 1, r
+ if (s(i) .ne. size(a,i)) stop 101
+ end do
+ end block
+
+ end subroutine
+
+ subroutine test1 (a)
+ integer :: a(*)
+
+ call testit (a)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2)
+ implicit none
+ integer :: l1, u1, l2, u2
+ integer :: a(l1:u1, l2:u2, *)
+
+ call testit (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/size-bindc.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/size-bindc.f90
@@ -0,0 +1,106 @@
+! Reported as pr94070.
+! { dg-do run }
+!
+! TS 29113
+! 6.4.2 SIZE
+!
+! The description of the intrinsic function SIZE in ISO/IEC 1539-1:2010
+! is changed in the following cases:
+!
+! (1) for an assumed-rank object that is associated with an assumed-size
+! array, the result has the value −1 if DIM is present and equal to the
+! rank of ARRAY, and a negative value that is equal to
+! PRODUCT ( [ (SIZE (ARRAY, I, KIND), I=1, RANK (ARRAY)) ] )
+! if DIM is not present;
+!
+! (2) for an assumed-rank object that is associated with a scalar, the
+! result has the value 1.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+
+program test
+
+ ! Define some arrays for testing.
+ integer, target :: x1(5)
+ integer :: y1(0:9)
+ integer, pointer :: p1(:)
+ integer, allocatable :: a1(:)
+ integer, target :: x3(2,3,4)
+ integer :: y3(0:1,-3:-1,4)
+ integer, pointer :: p3(:,:,:)
+ integer, allocatable :: a3(:,:,:)
+ integer :: x
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call test1 (y1)
+ p1 => x1
+ call test1 (p1)
+ allocate (a1(5))
+ call test1 (a1)
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+ ! Test scalars.
+ call test0 (x)
+ call test0 (-1)
+ call test0 (x1(1))
+
+contains
+
+ subroutine testit (a, r, sizes) bind(c)
+ integer :: a(..)
+ integer :: r
+ integer :: sizes(r)
+
+ integer :: totalsize, thissize
+ totalsize = 1
+
+ if (r .ne. rank(a)) stop 101
+
+ do i = 1, r
+ thissize = size (a, i)
+ print *, 'got size ', thissize, ' expected ', sizes(i)
+ if (thissize .ne. sizes(i)) stop 102
+ totalsize = totalsize * thissize
+ end do
+
+ if (size(a) .ne. totalsize) stop 103
+ end subroutine
+
+ subroutine test0 (a) bind(c)
+ integer :: a(..)
+
+ if (size (a) .ne. 1) stop 103
+ end subroutine
+
+ subroutine test1 (a) bind(c)
+ integer :: a(*)
+
+ integer :: sizes(1)
+ sizes(1) = -1
+ call testit (a, 1, sizes)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2) bind(c)
+ implicit none
+ integer :: l1, u1, l2, u2
+ integer :: a(l1:u1, l2:u2, *)
+
+ integer :: sizes(3)
+ sizes(1) = u1 - l1 + 1
+ sizes(2) = u2 - l2 + 1
+ sizes(3) = -1
+
+ call testit (a, 3, sizes)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/size-poly.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/size-poly.f90
@@ -0,0 +1,118 @@
+! Reported as pr94070.
+! { dg-do run }
+!
+! TS 29113
+! 6.4.2 SIZE
+!
+! The description of the intrinsic function SIZE in ISO/IEC 1539-1:2010
+! is changed in the following cases:
+!
+! (1) for an assumed-rank object that is associated with an assumed-size
+! array, the result has the value −1 if DIM is present and equal to the
+! rank of ARRAY, and a negative value that is equal to
+! PRODUCT ( [ (SIZE (ARRAY, I, KIND), I=1, RANK (ARRAY)) ] )
+! if DIM is not present;
+!
+! (2) for an assumed-rank object that is associated with a scalar, the
+! result has the value 1.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+!
+! This is the polymorphic version of size.f90.
+
+module m
+ type :: t
+ integer :: id
+ real :: xyz(3)
+ end type
+end module
+
+program test
+ use m
+
+ ! Define some arrays for testing.
+ type(t), target :: x1(5)
+ type(t) :: y1(0:9)
+ class(t), pointer :: p1(:)
+ class(t), allocatable :: a1(:)
+ type(t), target :: x3(2,3,4)
+ type(t) :: y3(0:1,-3:-1,4)
+ class(t), pointer :: p3(:,:,:)
+ type(t), allocatable :: a3(:,:,:)
+ type(t) :: x
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call test1 (y1)
+ p1 => x1
+ call test1 (p1)
+ allocate (a1(5))
+ call test1 (a1)
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+ ! Test scalars.
+ call test0 (x)
+ call test0 (x1(1))
+
+contains
+
+ subroutine testit (a, r, sizes)
+ use m
+ class(t) :: a(..)
+ integer :: r
+ integer :: sizes(r)
+
+ integer :: totalsize, thissize
+ totalsize = 1
+
+ if (r .ne. rank(a)) stop 101
+
+ do i = 1, r
+ thissize = size (a, i)
+ print *, 'got size ', thissize, ' expected ', sizes(i)
+ if (thissize .ne. sizes(i)) stop 102
+ totalsize = totalsize * thissize
+ end do
+
+ if (size(a) .ne. totalsize) stop 103
+ end subroutine
+
+ subroutine test0 (a)
+ use m
+ class(t) :: a(..)
+
+ if (size (a) .ne. 1) stop 103
+ end subroutine
+
+ subroutine test1 (a)
+ use m
+ class(t) :: a(*)
+
+ integer :: sizes(1)
+ sizes(1) = -1
+ call testit (a, 1, sizes)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2)
+ use m
+ integer :: l1, u1, l2, u2
+ class(t) :: a(l1:u1, l2:u2, *)
+
+ integer :: sizes(3)
+ sizes(1) = u1 - l1 + 1
+ sizes(2) = u2 - l2 + 1
+ sizes(3) = -1
+
+ call testit (a, 3, sizes)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/size.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/size.f90
@@ -0,0 +1,106 @@
+! Reported as pr94070.
+! { dg-do run }
+!
+! TS 29113
+! 6.4.2 SIZE
+!
+! The description of the intrinsic function SIZE in ISO/IEC 1539-1:2010
+! is changed in the following cases:
+!
+! (1) for an assumed-rank object that is associated with an assumed-size
+! array, the result has the value −1 if DIM is present and equal to the
+! rank of ARRAY, and a negative value that is equal to
+! PRODUCT ( [ (SIZE (ARRAY, I, KIND), I=1, RANK (ARRAY)) ] )
+! if DIM is not present;
+!
+! (2) for an assumed-rank object that is associated with a scalar, the
+! result has the value 1.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+
+program test
+
+ ! Define some arrays for testing.
+ integer, target :: x1(5)
+ integer :: y1(0:9)
+ integer, pointer :: p1(:)
+ integer, allocatable :: a1(:)
+ integer, target :: x3(2,3,4)
+ integer :: y3(0:1,-3:-1,4)
+ integer, pointer :: p3(:,:,:)
+ integer, allocatable :: a3(:,:,:)
+ integer :: x
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call test1 (y1)
+ p1 => x1
+ call test1 (p1)
+ allocate (a1(5))
+ call test1 (a1)
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+ ! Test scalars.
+ call test0 (x)
+ call test0 (-1)
+ call test0 (x1(1))
+
+contains
+
+ subroutine testit (a, r, sizes)
+ integer :: a(..)
+ integer :: r
+ integer :: sizes(r)
+
+ integer :: totalsize, thissize
+ totalsize = 1
+
+ if (r .ne. rank(a)) stop 101
+
+ do i = 1, r
+ thissize = size (a, i)
+ print *, 'got size ', thissize, ' expected ', sizes(i)
+ if (thissize .ne. sizes(i)) stop 102
+ totalsize = totalsize * thissize
+ end do
+
+ if (size(a) .ne. totalsize) stop 103
+ end subroutine
+
+ subroutine test0 (a)
+ integer :: a(..)
+
+ if (size (a) .ne. 1) stop 103
+ end subroutine
+
+ subroutine test1 (a)
+ integer :: a(*)
+
+ integer :: sizes(1)
+ sizes(1) = -1
+ call testit (a, 1, sizes)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2)
+ implicit none
+ integer :: l1, u1, l2, u2
+ integer :: a(l1:u1, l2:u2, *)
+
+ integer :: sizes(3)
+ sizes(1) = u1 - l1 + 1
+ sizes(2) = u2 - l2 + 1
+ sizes(3) = -1
+
+ call testit (a, 3, sizes)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/tkr.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/tkr.f90
@@ -0,0 +1,46 @@
+! { dg-do compile}
+!
+! TS 29113
+! The definition of TKR compatible in paragraph 2 of subclause 12.4.3.4.5
+! of ISO/IEC 1539-1:2010 is changed to:
+!
+! A dummy argument is type, kind, and rank compatible, or TKR compatible,
+! with another dummy argument if the first is type compatible with the
+! second, the kind type parameters of the first have the same values as
+! the corresponding kind type parameters of the second, and both have the
+! same rank or either is assumed-rank.
+!
+! This test file contains tests that are expected to issue diagnostics
+! for invalid code.
+
+module m
+
+interface foo
+ subroutine foo_1 (x) ! { dg-error "Ambiguous interfaces" }
+ integer :: x(..)
+ end subroutine
+ subroutine foo_2 (x) ! { dg-error "Ambiguous interfaces" }
+ integer :: x(:, :)
+ end subroutine
+end interface
+
+interface bar
+ subroutine bar_1 (x) ! { dg-error "Ambiguous interfaces" }
+ integer :: x(..)
+ end subroutine
+ subroutine bar_2 (x) ! { dg-error "Ambiguous interfaces" }
+ integer :: x(..)
+ end subroutine
+end interface
+
+interface baz
+ subroutine baz_1 (x) ! { dg-error "Ambiguous interfaces" }
+ integer :: x
+ end subroutine
+ subroutine baz_2 (x) ! { dg-error "Ambiguous interfaces" }
+ integer :: x(..)
+ end subroutine
+end interface
+
+end module
+
Index: Fortran/gfortran/regression/c-interop/typecodes-array-basic-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-basic-c.c
@@ -0,0 +1,169 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest_int1 (CFI_cdesc_t *arg_int,
+ CFI_cdesc_t *arg_short,
+ CFI_cdesc_t *arg_long,
+ CFI_cdesc_t *arg_long_long,
+ CFI_cdesc_t *arg_signed_char);
+
+extern void ctest_int2 (CFI_cdesc_t *arg_int8,
+ CFI_cdesc_t *arg_int16,
+ CFI_cdesc_t *arg_int32,
+ CFI_cdesc_t *arg_int64);
+
+extern void ctest_int3 (CFI_cdesc_t *arg_least8,
+ CFI_cdesc_t *arg_least16,
+ CFI_cdesc_t *arg_least32,
+ CFI_cdesc_t *arg_least64);
+
+extern void ctest_int4 (CFI_cdesc_t *arg_fast8,
+ CFI_cdesc_t *arg_fast16,
+ CFI_cdesc_t *arg_fast32,
+ CFI_cdesc_t *arg_fast64);
+
+extern void ctest_int5 (CFI_cdesc_t *arg_size,
+ CFI_cdesc_t *arg_intmax,
+ CFI_cdesc_t *arg_intptr,
+ CFI_cdesc_t *arg_ptrdiff);
+
+extern void ctest_real (CFI_cdesc_t *arg_float,
+ CFI_cdesc_t *arg_double);
+
+extern void ctest_complex (CFI_cdesc_t *arg_float_complex,
+ CFI_cdesc_t *arg_double_complex);
+
+extern void ctest_misc (CFI_cdesc_t *arg_bool,
+ CFI_cdesc_t *arg_cptr,
+ CFI_cdesc_t *arg_cfunptr,
+ CFI_cdesc_t *arg_struct);
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->base_addr == NULL)
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+
+/* Test that the basic integer types correspond correctly. */
+void
+ctest_int1 (CFI_cdesc_t *arg_int,
+ CFI_cdesc_t *arg_short,
+ CFI_cdesc_t *arg_long,
+ CFI_cdesc_t *arg_long_long,
+ CFI_cdesc_t *arg_signed_char)
+{
+ check (arg_int, sizeof (int), CFI_type_int);
+ check (arg_short, sizeof (short), CFI_type_short);
+ check (arg_long, sizeof (long), CFI_type_long);
+ check (arg_long_long, sizeof (long long int), CFI_type_long_long);
+ check (arg_signed_char, sizeof (signed char), CFI_type_signed_char);
+}
+
+/* Test the integer types of explicit sizes. */
+void
+ctest_int2 (CFI_cdesc_t *arg_int8,
+ CFI_cdesc_t *arg_int16,
+ CFI_cdesc_t *arg_int32,
+ CFI_cdesc_t *arg_int64)
+{
+ check (arg_int8, sizeof (int8_t), CFI_type_int8_t);
+ check (arg_int16, sizeof (int16_t), CFI_type_int16_t);
+ check (arg_int32, sizeof (int32_t), CFI_type_int32_t);
+ check (arg_int64, sizeof (int64_t), CFI_type_int64_t);
+}
+
+/* Check the int_least*_t types. */
+
+void
+ctest_int3 (CFI_cdesc_t *arg_least8,
+ CFI_cdesc_t *arg_least16,
+ CFI_cdesc_t *arg_least32,
+ CFI_cdesc_t *arg_least64)
+{
+ check (arg_least8, sizeof (int_least8_t), CFI_type_int_least8_t);
+ check (arg_least16, sizeof (int_least16_t), CFI_type_int_least16_t);
+ check (arg_least32, sizeof (int_least32_t), CFI_type_int_least32_t);
+ check (arg_least64, sizeof (int_least64_t), CFI_type_int_least64_t);
+}
+
+/* Check the int_fast*_t types. */
+void
+ctest_int4 (CFI_cdesc_t *arg_fast8,
+ CFI_cdesc_t *arg_fast16,
+ CFI_cdesc_t *arg_fast32,
+ CFI_cdesc_t *arg_fast64)
+{
+ check (arg_fast8, sizeof (int_fast8_t), CFI_type_int_fast8_t);
+ check (arg_fast16, sizeof (int_fast16_t), CFI_type_int_fast16_t);
+ check (arg_fast32, sizeof (int_fast32_t), CFI_type_int_fast32_t);
+ check (arg_fast64, sizeof (int_fast64_t), CFI_type_int_fast64_t);
+}
+
+/* Check the "purposeful" integer types. */
+void
+ctest_int5 (CFI_cdesc_t *arg_size,
+ CFI_cdesc_t *arg_intmax,
+ CFI_cdesc_t *arg_intptr,
+ CFI_cdesc_t *arg_ptrdiff)
+{
+ check (arg_size, sizeof (size_t), CFI_type_size_t);
+ check (arg_intmax, sizeof (intmax_t), CFI_type_intmax_t);
+ check (arg_intptr, sizeof (intptr_t), CFI_type_intptr_t);
+ check (arg_ptrdiff, sizeof (ptrdiff_t), CFI_type_ptrdiff_t);
+}
+
+/* Check the floating-point types. */
+void
+ctest_real (CFI_cdesc_t *arg_float,
+ CFI_cdesc_t *arg_double)
+{
+ check (arg_float, sizeof (float), CFI_type_float);
+ check (arg_double, sizeof (double), CFI_type_double);
+}
+
+/* Likewise for the complex types. */
+void
+ctest_complex (CFI_cdesc_t *arg_float_complex,
+ CFI_cdesc_t *arg_double_complex)
+{
+ check (arg_float_complex, sizeof (float _Complex),
+ CFI_type_float_Complex);
+ check (arg_double_complex, sizeof (double _Complex),
+ CFI_type_double_Complex);
+}
+
+/* Misc types. */
+void
+ctest_misc (CFI_cdesc_t *arg_bool,
+ CFI_cdesc_t *arg_cptr,
+ CFI_cdesc_t *arg_cfunptr,
+ CFI_cdesc_t *arg_struct)
+{
+ struct m
+ {
+ int i, j;
+ };
+
+ check (arg_bool, sizeof (_Bool), CFI_type_Bool);
+ check (arg_cptr, sizeof (void *), CFI_type_cptr);
+ check (arg_cfunptr, sizeof (void (*)(void)), CFI_type_cfunptr);
+ check (arg_struct, sizeof (struct m), CFI_type_struct);
+}
Index: Fortran/gfortran/regression/c-interop/typecodes-array-basic.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-basic.f90
@@ -0,0 +1,151 @@
+! PR 101305
+! PR 100917
+! { dg-do run }
+! { dg-additional-sources "typecodes-array-basic-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that kind constants in the ISO_C_BINDING
+! module result in the right type field in arguments passed by descriptor,
+! also matching the size of the corresponding C type. We use
+! assumed-rank arrays to force the use of a descriptor.
+!
+! Some types are tested in their own testcases to allow conditionalization
+! for target-specific support or xfailing to track bugs.
+
+module mm
+ use iso_c_binding
+
+ type, bind (c) :: s
+ integer(C_INT) :: i, j
+ end type
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+
+ subroutine ctest_int1 (arg_int, arg_short, arg_long, arg_long_long, &
+ arg_signed_char) bind (c)
+ use iso_c_binding
+ integer(C_INT) :: arg_int(:)
+ integer(C_SHORT) :: arg_short(:)
+ integer(C_LONG) :: arg_long(:)
+ integer(C_LONG_LONG) :: arg_long_long(:)
+ integer(C_SIGNED_CHAR) :: arg_signed_char(:)
+ end subroutine
+
+ subroutine ctest_int2 (arg_int8, arg_int16, arg_int32, arg_int64) bind (c)
+ use iso_c_binding
+ integer(C_INT8_T) :: arg_int8(:)
+ integer(C_INT16_T) :: arg_int16(:)
+ integer(C_INT32_T) :: arg_int32(:)
+ integer(C_INT64_T) :: arg_int64(:)
+ end subroutine
+
+ subroutine ctest_int3 (arg_least8, arg_least16, arg_least32, &
+ arg_least64) bind (c)
+ use iso_c_binding
+ integer(C_INT_LEAST8_T) :: arg_least8(:)
+ integer(C_INT_LEAST16_T) :: arg_least16(:)
+ integer(C_INT_LEAST32_T) :: arg_least32(:)
+ integer(C_INT_LEAST64_T) :: arg_least64(:)
+ end subroutine
+
+ subroutine ctest_int4 (arg_fast8, arg_fast16, arg_fast32, &
+ arg_fast64) bind (c)
+ use iso_c_binding
+ integer(C_INT_FAST8_T) :: arg_fast8(:)
+ integer(C_INT_FAST16_T) :: arg_fast16(:)
+ integer(C_INT_FAST32_T) :: arg_fast32(:)
+ integer(C_INT_FAST64_T) :: arg_fast64(:)
+ end subroutine
+
+ subroutine ctest_int5 (arg_size, arg_intmax, arg_intptr, &
+ arg_ptrdiff) bind (c)
+ use iso_c_binding
+ integer(C_SIZE_T) :: arg_size(:)
+ integer(C_INTMAX_T) :: arg_intmax(:)
+ integer(C_INTPTR_T) :: arg_intptr(:)
+ integer(C_PTRDIFF_T) :: arg_ptrdiff(:)
+ end subroutine
+
+ subroutine ctest_real (arg_float, arg_double) bind (c)
+ use iso_c_binding
+ real(C_FLOAT) :: arg_float(:)
+ real(C_DOUBLE) :: arg_double(:)
+ end subroutine
+
+ subroutine ctest_complex (arg_float_complex, arg_double_complex) &
+ bind (c)
+ use iso_c_binding
+ complex(C_FLOAT_COMPLEX) :: arg_float_complex(:)
+ complex(C_DOUBLE_COMPLEX) :: arg_double_complex(:)
+ end subroutine
+
+ subroutine ctest_misc (arg_bool, arg_cptr, arg_cfunptr, &
+ arg_struct) bind (c)
+ use iso_c_binding
+ use mm
+ logical(C_BOOL) :: arg_bool(:)
+ type(C_PTR) :: arg_cptr(:)
+ type(C_FUNPTR) :: arg_cfunptr(:)
+ type(s) :: arg_struct(:)
+ end subroutine
+
+ end interface
+
+ integer(C_INT) :: var_int(4)
+ integer(C_SHORT) :: var_short(4)
+ integer(C_LONG) :: var_long(4)
+ integer(C_LONG_LONG) :: var_long_long(4)
+ integer(C_SIGNED_CHAR) :: var_signed_char(4)
+ integer(C_INT8_T) :: var_int8(4)
+ integer(C_INT16_T) :: var_int16(4)
+ integer(C_INT32_T) :: var_int32(4)
+ integer(C_INT64_T) :: var_int64(4)
+ integer(C_INT_LEAST8_T) :: var_least8(4)
+ integer(C_INT_LEAST16_T) :: var_least16(4)
+ integer(C_INT_LEAST32_T) :: var_least32(4)
+ integer(C_INT_LEAST64_T) :: var_least64(4)
+ integer(C_INT_FAST8_T) :: var_fast8(4)
+ integer(C_INT_FAST16_T) :: var_fast16(4)
+ integer(C_INT_FAST32_T) :: var_fast32(4)
+ integer(C_INT_FAST64_T) :: var_fast64(4)
+ integer(C_SIZE_T) :: var_size(4)
+ integer(C_INTMAX_T) :: var_intmax(4)
+ integer(C_INTPTR_T) :: var_intptr(4)
+ integer(C_PTRDIFF_T) :: var_ptrdiff(4)
+ real(C_FLOAT) :: var_float(4)
+ real(C_DOUBLE) :: var_double(4)
+ complex(C_FLOAT_COMPLEX) :: var_float_complex(4)
+ complex(C_DOUBLE_COMPLEX) :: var_double_complex(4)
+ logical(C_BOOL) :: var_bool(4)
+ type(C_PTR) :: var_cptr(4)
+ type(C_FUNPTR) :: var_cfunptr(4)
+ type(s) :: var_struct(4)
+
+ call ctest_int1 (var_int, var_short, var_long, var_long_long, &
+ var_signed_char)
+
+ call ctest_int2 (var_int8, var_int16, var_int32, var_int64)
+
+ call ctest_int3 (var_least8, var_least16, var_least32, var_least64)
+
+ call ctest_int4 (var_fast8, var_fast16, var_fast32, var_fast64)
+
+ call ctest_int5 (var_size, var_intmax, var_intptr, var_ptrdiff)
+
+ call ctest_real (var_float, var_double)
+
+ call ctest_complex (var_float_complex, var_double_complex)
+
+ call ctest_misc (var_bool, var_cptr, var_cfunptr, var_struct)
+
+ ! FIXME: how do you pass something that corresponds to CFI_type_other?
+ ! The Fortran front end complains if you try to pass something that
+ ! isn't interoperable, such as a derived type object without bind(c).
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-array-char-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-char-c.c
@@ -0,0 +1,41 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest_1 (CFI_cdesc_t *arg_char, CFI_cdesc_t *arg_ucs4);
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->base_addr == NULL)
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+void
+ctest_1 (CFI_cdesc_t *arg_char, CFI_cdesc_t *arg_ucs4)
+{
+ check (arg_char, 1, CFI_type_char);
+ check (arg_ucs4, 4, CFI_type_ucs4_char);
+}
+
+void
+ctest_5 (CFI_cdesc_t *arg_char, CFI_cdesc_t *arg_ucs4)
+{
+ check (arg_char, 5*1, CFI_type_char);
+ check (arg_ucs4, 5*4, CFI_type_ucs4_char);
+}
Index: Fortran/gfortran/regression/c-interop/typecodes-array-char.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-char.f90
@@ -0,0 +1,47 @@
+! PR 101305
+! PR 92482
+! { dg-do run }
+! { dg-additional-sources "typecodes-array-char-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that the character kind constants provided by
+! gfortran's ISO_C_BINDING module result in the right type field in
+! arguments passed by descriptor, also matching the size of the corresponding
+! C type. We use assumed-shape arrays to force the use of a descriptor.
+!
+! FIXME: because of PR92482, we can only test len=1 characters. This
+! test should be extended once that bug is fixed.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ integer, parameter :: ucs4 = selected_char_kind ('ISO_10646')
+
+ interface
+
+ subroutine ctest_1 (arg_cchar, arg_ucs4) bind (c)
+ use iso_c_binding
+ integer, parameter :: ucs4 = selected_char_kind ('ISO_10646')
+ character(kind=C_CHAR) :: arg_cchar(:)
+ character(kind=ucs4) :: arg_ucs4(:)
+ end subroutine
+
+ subroutine ctest_5 (arg_cchar, arg_ucs4) bind (c)
+ use iso_c_binding
+ integer, parameter :: ucs4 = selected_char_kind ('ISO_10646')
+ character(kind=C_CHAR,len=*) :: arg_cchar(:)
+ character(kind=ucs4,len=*) :: arg_ucs4(:)
+ end subroutine
+
+ end interface
+
+ character(kind=C_CHAR) :: var_cchar(4)
+ character(kind=ucs4) :: var_ucs4(4)
+ character(kind=C_CHAR,len=5) :: var_cchar_5(4)
+ character(kind=ucs4,len=5) :: var_ucs4_5(4)
+
+ call ctest_1 (var_cchar, var_ucs4)
+ call ctest_5 (var_cchar_5, var_ucs4_5)
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-array-float128-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-float128-c.c
@@ -0,0 +1,38 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *arg_float128,
+ CFI_cdesc_t *arg_complex128);
+
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->base_addr == NULL)
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+void
+ctest (CFI_cdesc_t *arg_float128,
+ CFI_cdesc_t *arg_complex128)
+{
+ check (arg_float128, sizeof (_Float128), CFI_type_float128);
+ check (arg_complex128, sizeof (_Float128) * 2,
+ CFI_type_float128_Complex);
+}
Index: Fortran/gfortran/regression/c-interop/typecodes-array-float128.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-float128.f90
@@ -0,0 +1,34 @@
+! PR 101305
+! PR 100914
+! PR 100917
+! Fails on x86 targets where sizeof(long double) == 16 (PR100917).
+! { dg-do run }
+! { dg-require-effective-target fortran_real_c_float128 }
+! { dg-additional-sources "typecodes-array-float128-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that the vendor extension kind constants provided by
+! gfortran's ISO_C_BINDING module result in the right type field in
+! arguments passed by descriptor, also matching the size of the corresponding
+! C type. We use assumed-shape arrays to force the use of a descriptor.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+
+ subroutine ctest (arg_float128, arg_complex128) bind (c)
+ use iso_c_binding
+ real(C_FLOAT128) :: arg_float128(:)
+ complex(C_FLOAT128_COMPLEX) :: arg_complex128(:)
+ end subroutine
+
+ end interface
+
+ real(C_FLOAT128) :: var_float128(4)
+ complex(C_FLOAT128_COMPLEX) :: var_complex128(4)
+
+ call ctest (var_float128, var_complex128)
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-array-int128-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-int128-c.c
@@ -0,0 +1,40 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *arg_int128,
+ CFI_cdesc_t *arg_least128,
+ CFI_cdesc_t *arg_fast128);
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->base_addr == NULL)
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+void
+ctest (CFI_cdesc_t *arg_int128,
+ CFI_cdesc_t *arg_least128,
+ CFI_cdesc_t *arg_fast128)
+{
+ check (arg_int128, sizeof (__int128), CFI_type_int128_t);
+ check (arg_least128, sizeof (__int128), CFI_type_int_least128_t);
+ check (arg_fast128, sizeof (__int128), CFI_type_int_fast128_t);
+}
+
Index: Fortran/gfortran/regression/c-interop/typecodes-array-int128.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-int128.f90
@@ -0,0 +1,33 @@
+! PR 101305
+! { dg-do run }
+! { dg-require-effective-target fortran_integer_16 }
+! { dg-additional-sources "typecodes-array-int128-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that 128-bit integer kind constants provided by
+! gfortran's ISO_C_BINDING module result in the right type field in
+! arguments passed by descriptor, also matching the size of the corresponding
+! C type. We use assumed-shape arrays to force the use of a descriptor.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+
+ subroutine ctest (arg_int128, arg_least128, arg_fast128) bind (c)
+ use iso_c_binding
+ integer(C_INT128_T) :: arg_int128(:)
+ integer(C_INT_LEAST128_T) :: arg_least128(:)
+ integer(C_INT_FAST128_T) :: arg_fast128(:)
+ end subroutine
+
+ end interface
+
+ integer(C_INT128_T) :: var_int128(4)
+ integer(C_INT_LEAST128_T) :: var_least128(4)
+ integer(C_INT_FAST128_T) :: var_fast128(4)
+
+ call ctest (var_int128, var_least128, var_fast128)
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-array-longdouble-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-longdouble-c.c
@@ -0,0 +1,37 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *arg_long_double,
+ CFI_cdesc_t *arg_long_double_complex);
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_other)
+ abort ();
+ if (a->base_addr == NULL)
+ abort ();
+ if (a->rank != 1)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+void
+ctest (CFI_cdesc_t *arg_long_double,
+ CFI_cdesc_t *arg_long_double_complex)
+{
+ check (arg_long_double, sizeof (long double), CFI_type_long_double);
+ check (arg_long_double_complex, sizeof (long double _Complex),
+ CFI_type_long_double_Complex);
+}
Index: Fortran/gfortran/regression/c-interop/typecodes-array-longdouble.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-array-longdouble.f90
@@ -0,0 +1,32 @@
+! PR 101305
+! PR 100917
+! { dg-do run }
+! { dg-additional-sources "typecodes-array-longdouble-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that long double kind constants in the ISO_C_BINDING
+! module result in the right type field in arguments passed by descriptor,
+! also matching the size of the corresponding C type. We use
+! assumed-rank arrays to force the use of a descriptor.
+
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+
+ subroutine ctest (arg_long_double, arg_long_double_complex) bind (c)
+ use iso_c_binding
+ real(C_LONG_DOUBLE) :: arg_long_double(:)
+ complex(C_LONG_DOUBLE_COMPLEX) :: arg_long_double_complex(:)
+ end subroutine
+
+ end interface
+
+ real(C_LONG_DOUBLE) :: var_long_double(4)
+ complex(C_LONG_DOUBLE_COMPLEX) :: var_long_double_complex(4)
+
+ call ctest (var_long_double, var_long_double_complex)
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-sanity-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-sanity-c.c
@@ -0,0 +1,178 @@
+#include
+#include
+#include
+#include
+
+#include
+
+extern void ctest_typecodes (void);
+
+/* Do sanity checking on the CFI_type_* macros. In particular, make sure
+ that if two type codes have the same value, they represent objects of the
+ same size. */
+
+struct tc_info
+{
+ CFI_type_t typecode;
+ char *name;
+ size_t size;
+ int extension;
+};
+
+static struct tc_info tc_table[] =
+{
+ /* Extension types.
+ Note there is no portable C equivalent type for CFI_type_ucs4_char type
+ (4-byte Unicode characters), so this is kind of hacky... */
+#if CFI_type_int128_t > 0
+ { CFI_type_int128_t, "CFI_type_int128_t",
+ sizeof (__int128), 1 },
+ { CFI_type_int_least128_t, "CFI_type_int_least128_t",
+ sizeof (__int128), 1 },
+ { CFI_type_int_fast128_t, "CFI_type_int_fast128_t",
+ sizeof (__int128), 1 },
+#endif
+#if CFI_type_ucs4_char > 0
+ { CFI_type_ucs4_char, "CFI_type_ucs4_char", 4, 1 },
+#endif
+#if CFI_type_float128 > 0
+ { CFI_type_float128, "CFI_type_float128",
+ sizeof (_Float128), 1 },
+ { CFI_type_float128_Complex, "CFI_type_float128_Complex",
+ sizeof (_Float128 _Complex), 1 },
+#endif
+#if CFI_type_cfunptr > 0
+ { CFI_type_cfunptr, "CFI_type_cfunptr",
+ sizeof (void (*)(void)), 1 },
+#endif
+
+ /* Standard types. */
+ { CFI_type_signed_char, "CFI_type_signed_char",
+ sizeof (signed char), 0, },
+ { CFI_type_short, "CFI_type_short",
+ sizeof (short), 0 },
+ { CFI_type_int, "CFI_type_int",
+ sizeof (int), 0 },
+ { CFI_type_long, "CFI_type_long",
+ sizeof (long), 0 },
+ { CFI_type_long_long, "CFI_type_long_long",
+ sizeof (long long), 0 },
+ { CFI_type_size_t, "CFI_type_size_t",
+ sizeof (size_t), 0 },
+ { CFI_type_int8_t, "CFI_type_int8_t",
+ sizeof (int8_t), 0 },
+ { CFI_type_int16_t, "CFI_type_int16_t",
+ sizeof (int16_t), 0 },
+ { CFI_type_int32_t, "CFI_type_int32_t",
+ sizeof (int32_t), 0 },
+ { CFI_type_int64_t, "CFI_type_int64_t",
+ sizeof (int64_t), 0 },
+ { CFI_type_int_least8_t, "CFI_type_int_least8_t",
+ sizeof (int_least8_t), 0 },
+ { CFI_type_int_least16_t, "CFI_type_int_least16_t",
+ sizeof (int_least16_t), 0 },
+ { CFI_type_int_least32_t, "CFI_type_int_least32_t",
+ sizeof (int_least32_t), 0 },
+ { CFI_type_int_least64_t, "CFI_type_int_least64_t",
+ sizeof (int_least64_t), 0 },
+ { CFI_type_int_fast8_t, "CFI_type_int_fast8_t",
+ sizeof (int_fast8_t), 0 },
+ { CFI_type_int_fast16_t, "CFI_type_int_fast16_t",
+ sizeof (int_fast16_t), 0 },
+ { CFI_type_int_fast32_t, "CFI_type_int_fast32_t",
+ sizeof (int_fast32_t), 0 },
+ { CFI_type_int_fast64_t, "CFI_type_int_fast64_t",
+ sizeof (int_fast64_t), 0 },
+ { CFI_type_intmax_t, "CFI_type_intmax_t",
+ sizeof (intmax_t), 0 },
+ { CFI_type_intptr_t, "CFI_type_intptr_t",
+ sizeof (intptr_t), 0 },
+ { CFI_type_ptrdiff_t, "CFI_type_ptrdiff_t",
+ sizeof (ptrdiff_t), 0 },
+ { CFI_type_float, "CFI_type_float",
+ sizeof (float), 0 },
+ { CFI_type_double, "CFI_type_double",
+ sizeof (double), 0 },
+ { CFI_type_long_double, "CFI_type_long_double",
+ sizeof (long double), 0 },
+ { CFI_type_float_Complex, "CFI_type_float_Complex",
+ sizeof (float _Complex), 0 },
+ { CFI_type_double_Complex, "CFI_type_double_Complex",
+ sizeof (double _Complex), 0 },
+ { CFI_type_long_double_Complex, "CFI_type_long_double_Complex",
+ sizeof (long double _Complex), 0 },
+ { CFI_type_Bool, "CFI_type_Bool",
+ sizeof (_Bool), 0 },
+ { CFI_type_char, "CFI_type_char",
+ sizeof (char), 0 },
+ { CFI_type_cptr, "CFI_type_cptr",
+ sizeof (void *), 0 },
+ { CFI_type_struct, "CFI_type_struct", 0, 0 },
+ { CFI_type_other, "CFI_type_other", -1, 0, }
+};
+
+void
+ctest_typecodes (void)
+{
+ int ncodes = sizeof (tc_table) / sizeof (struct tc_info);
+ int i, j;
+ int bad = 0;
+
+ for (i = 0; i < ncodes; i++)
+ for (j = i + 1; j < ncodes; j++)
+ if (tc_table[i].typecode == tc_table[j].typecode
+ && tc_table[i].typecode > 0
+ && (tc_table[i].size != tc_table[j].size))
+ {
+ fprintf (stderr,
+ "type codes have the same value %d but different sizes\n",
+ (int) tc_table[i].typecode);
+ fprintf (stderr, " %s size %d\n",
+ tc_table[i].name, (int) tc_table[i].size);
+ fprintf (stderr, " %s size %d\n",
+ tc_table[j].name, (int) tc_table[j].size);
+ bad = 1;
+ }
+
+ /* TS29113 Section 8.3.4: The value for CFI_type_other shall be negative
+ and distinct from all other type specifiers. If a C type is not
+ interoperable with a Fortran type and kind supported by the
+ Fortran processor, its macro shall evaluate to a negative value.
+ Otherwise, the value for an intrinsic type shall be positive.
+
+ In the case of GCC, we expect that all the standard intrinsic
+ types are supported by both Fortran and C, so they should all be
+ positive except for CFI_type_other. Non-standard ones may have a
+ value -2. */
+
+ for (i = 0; i < ncodes; i++)
+ {
+ if (tc_table[i].typecode == CFI_type_other)
+ {
+ if (tc_table[i].typecode >= 0)
+ {
+ fprintf (stderr, "%s value %d is not negative\n",
+ tc_table[i].name, (int)tc_table[i].typecode);
+ bad = 1;
+ }
+ if (strcmp (tc_table[i].name, "CFI_type_other"))
+ {
+ fprintf (stderr, "%s has the same value %d as CFI_type_other\n",
+ tc_table[i].name, (int)CFI_type_other);
+ bad = 1;
+ }
+ }
+ else if (tc_table[i].typecode == -2 && tc_table[i].extension)
+ /* Unsupported extension type on this target; this is OK */
+ ;
+ else if (tc_table[i].typecode <= 0)
+ {
+ fprintf (stderr, "%s value %d is not positive\n",
+ tc_table[i].name, (int)tc_table[i].typecode);
+ bad = 1;
+ }
+ }
+
+ if (bad)
+ abort ();
+}
Index: Fortran/gfortran/regression/c-interop/typecodes-sanity.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-sanity.f90
@@ -0,0 +1,24 @@
+! PR 101305
+! { dg-do run }
+! { dg-additional-sources "typecodes-sanity-c.c" }
+! { dg-additional-options "-g" }
+!
+! This program does sanity checking on the CFI_type_* macros. All
+! of the interesting things happen on the C side.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ integer, parameter :: ucs4 = selected_char_kind ('ISO_10646')
+
+ interface
+
+ subroutine ctest_typecodes () bind (c)
+ end subroutine
+
+ end interface
+
+ call ctest_typecodes ()
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-scalar-basic-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-scalar-basic-c.c
@@ -0,0 +1,168 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest_int1 (CFI_cdesc_t *arg_int,
+ CFI_cdesc_t *arg_short,
+ CFI_cdesc_t *arg_long,
+ CFI_cdesc_t *arg_long_long,
+ CFI_cdesc_t *arg_signed_char);
+
+extern void ctest_int2 (CFI_cdesc_t *arg_int8,
+ CFI_cdesc_t *arg_int16,
+ CFI_cdesc_t *arg_int32,
+ CFI_cdesc_t *arg_int64);
+
+extern void ctest_int3 (CFI_cdesc_t *arg_least8,
+ CFI_cdesc_t *arg_least16,
+ CFI_cdesc_t *arg_least32,
+ CFI_cdesc_t *arg_least64);
+
+extern void ctest_int4 (CFI_cdesc_t *arg_fast8,
+ CFI_cdesc_t *arg_fast16,
+ CFI_cdesc_t *arg_fast32,
+ CFI_cdesc_t *arg_fast64);
+
+extern void ctest_int5 (CFI_cdesc_t *arg_size,
+ CFI_cdesc_t *arg_intmax,
+ CFI_cdesc_t *arg_intptr,
+ CFI_cdesc_t *arg_ptrdiff);
+
+extern void ctest_real (CFI_cdesc_t *arg_float,
+ CFI_cdesc_t *arg_double);
+
+extern void ctest_complex (CFI_cdesc_t *arg_float_complex,
+ CFI_cdesc_t *arg_double_complex);
+
+extern void ctest_misc (CFI_cdesc_t *arg_bool,
+ CFI_cdesc_t *arg_cptr,
+ CFI_cdesc_t *arg_cfunptr,
+ CFI_cdesc_t *arg_struct);
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_pointer)
+ abort ();
+ if (a->base_addr != NULL)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+
+/* Test that the basic integer types correspond correctly. */
+void
+ctest_int1 (CFI_cdesc_t *arg_int,
+ CFI_cdesc_t *arg_short,
+ CFI_cdesc_t *arg_long,
+ CFI_cdesc_t *arg_long_long,
+ CFI_cdesc_t *arg_signed_char)
+{
+ check (arg_int, sizeof (int), CFI_type_int);
+ check (arg_short, sizeof (short), CFI_type_short);
+ check (arg_long, sizeof (long), CFI_type_long);
+ check (arg_long_long, sizeof (long long int), CFI_type_long_long);
+ check (arg_signed_char, sizeof (signed char), CFI_type_signed_char);
+}
+
+/* Test the integer types of explicit sizes. */
+void
+ctest_int2 (CFI_cdesc_t *arg_int8,
+ CFI_cdesc_t *arg_int16,
+ CFI_cdesc_t *arg_int32,
+ CFI_cdesc_t *arg_int64)
+{
+ check (arg_int8, sizeof (int8_t), CFI_type_int8_t);
+ check (arg_int16, sizeof (int16_t), CFI_type_int16_t);
+ check (arg_int32, sizeof (int32_t), CFI_type_int32_t);
+ check (arg_int64, sizeof (int64_t), CFI_type_int64_t);
+}
+
+/* Check the int_least*_t types. */
+
+void
+ctest_int3 (CFI_cdesc_t *arg_least8,
+ CFI_cdesc_t *arg_least16,
+ CFI_cdesc_t *arg_least32,
+ CFI_cdesc_t *arg_least64)
+{
+ check (arg_least8, sizeof (int_least8_t), CFI_type_int_least8_t);
+ check (arg_least16, sizeof (int_least16_t), CFI_type_int_least16_t);
+ check (arg_least32, sizeof (int_least32_t), CFI_type_int_least32_t);
+ check (arg_least64, sizeof (int_least64_t), CFI_type_int_least64_t);
+}
+
+/* Check the int_fast*_t types. */
+void
+ctest_int4 (CFI_cdesc_t *arg_fast8,
+ CFI_cdesc_t *arg_fast16,
+ CFI_cdesc_t *arg_fast32,
+ CFI_cdesc_t *arg_fast64)
+{
+ check (arg_fast8, sizeof (int_fast8_t), CFI_type_int_fast8_t);
+ check (arg_fast16, sizeof (int_fast16_t), CFI_type_int_fast16_t);
+ check (arg_fast32, sizeof (int_fast32_t), CFI_type_int_fast32_t);
+ check (arg_fast64, sizeof (int_fast64_t), CFI_type_int_fast64_t);
+}
+
+/* Check the "purposeful" integer types. */
+void
+ctest_int5 (CFI_cdesc_t *arg_size,
+ CFI_cdesc_t *arg_intmax,
+ CFI_cdesc_t *arg_intptr,
+ CFI_cdesc_t *arg_ptrdiff)
+{
+ check (arg_size, sizeof (size_t), CFI_type_size_t);
+ check (arg_intmax, sizeof (intmax_t), CFI_type_intmax_t);
+ check (arg_intptr, sizeof (intptr_t), CFI_type_intptr_t);
+ check (arg_ptrdiff, sizeof (ptrdiff_t), CFI_type_ptrdiff_t);
+}
+
+/* Check the floating-point types. */
+void
+ctest_real (CFI_cdesc_t *arg_float,
+ CFI_cdesc_t *arg_double)
+{
+ check (arg_float, sizeof (float), CFI_type_float);
+ check (arg_double, sizeof (double), CFI_type_double);
+}
+
+/* Likewise for the complex types. */
+void
+ctest_complex (CFI_cdesc_t *arg_float_complex,
+ CFI_cdesc_t *arg_double_complex)
+{
+ check (arg_float_complex, sizeof (float _Complex),
+ CFI_type_float_Complex);
+ check (arg_double_complex, sizeof (double _Complex),
+ CFI_type_double_Complex);
+}
+
+/* Misc types. */
+void
+ctest_misc (CFI_cdesc_t *arg_bool,
+ CFI_cdesc_t *arg_cptr,
+ CFI_cdesc_t *arg_cfunptr,
+ CFI_cdesc_t *arg_struct)
+{
+ struct m
+ {
+ int i, j;
+ };
+
+ check (arg_bool, sizeof (_Bool), CFI_type_Bool);
+ check (arg_cptr, sizeof (void *), CFI_type_cptr);
+ check (arg_struct, sizeof (struct m), CFI_type_struct);
+}
Index: Fortran/gfortran/regression/c-interop/typecodes-scalar-basic.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-scalar-basic.f90
@@ -0,0 +1,160 @@
+! PR 101305
+! PR 100917
+! xfailed due to PR 101308
+! { dg-do run }
+! { dg-additional-sources "typecodes-scalar-basic-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that kind constants in the ISO_C_BINDING
+! module result in the right type field in arguments passed by descriptor,
+! also matching the size of the corresponding C type. We use pointers
+! to force the use of a descriptor.
+!
+! Some types are tested in their own testcases to allow conditionalization
+! for target-specific support or xfailing to track bugs.
+
+module mm
+ use iso_c_binding
+
+ type, bind (c) :: s
+ integer(C_INT) :: i, j
+ end type
+end module
+
+program testit
+ use iso_c_binding
+ use mm
+ implicit none
+
+ interface
+
+ subroutine ctest_int1 (arg_int, arg_short, arg_long, arg_long_long, &
+ arg_signed_char) bind (c)
+ use iso_c_binding
+ integer(C_INT), pointer :: arg_int
+ integer(C_SHORT), pointer :: arg_short
+ integer(C_LONG), pointer :: arg_long
+ integer(C_LONG_LONG), pointer :: arg_long_long
+ integer(C_SIGNED_CHAR), pointer :: arg_signed_char
+ end subroutine
+
+ subroutine ctest_int2 (arg_int8, arg_int16, arg_int32, arg_int64) bind (c)
+ use iso_c_binding
+ integer(C_INT8_T), pointer :: arg_int8
+ integer(C_INT16_T), pointer :: arg_int16
+ integer(C_INT32_T), pointer :: arg_int32
+ integer(C_INT64_T), pointer :: arg_int64
+ end subroutine
+
+ subroutine ctest_int3 (arg_least8, arg_least16, arg_least32, &
+ arg_least64) bind (c)
+ use iso_c_binding
+ integer(C_INT_LEAST8_T), pointer :: arg_least8
+ integer(C_INT_LEAST16_T), pointer :: arg_least16
+ integer(C_INT_LEAST32_T), pointer :: arg_least32
+ integer(C_INT_LEAST64_T), pointer :: arg_least64
+ end subroutine
+
+ subroutine ctest_int4 (arg_fast8, arg_fast16, arg_fast32, &
+ arg_fast64) bind (c)
+ use iso_c_binding
+ integer(C_INT_FAST8_T), pointer :: arg_fast8
+ integer(C_INT_FAST16_T), pointer :: arg_fast16
+ integer(C_INT_FAST32_T), pointer :: arg_fast32
+ integer(C_INT_FAST64_T), pointer :: arg_fast64
+ end subroutine
+
+ subroutine ctest_int5 (arg_size, arg_intmax, arg_intptr, &
+ arg_ptrdiff) bind (c)
+ use iso_c_binding
+ integer(C_SIZE_T), pointer :: arg_size
+ integer(C_INTMAX_T), pointer :: arg_intmax
+ integer(C_INTPTR_T), pointer :: arg_intptr
+ integer(C_PTRDIFF_T), pointer :: arg_ptrdiff
+ end subroutine
+
+ subroutine ctest_real (arg_float, arg_double) bind (c)
+ use iso_c_binding
+ real(C_FLOAT), pointer :: arg_float
+ real(C_DOUBLE), pointer :: arg_double
+ end subroutine
+
+ subroutine ctest_complex (arg_float_complex, arg_double_complex) &
+ bind (c)
+ use iso_c_binding
+ complex(C_FLOAT_COMPLEX), pointer :: arg_float_complex
+ complex(C_DOUBLE_COMPLEX), pointer :: arg_double_complex
+ end subroutine
+
+ subroutine ctest_misc (arg_bool, arg_cptr, arg_cfunptr, arg_struct) &
+ bind (c)
+ use iso_c_binding
+ use mm
+ logical(C_BOOL), pointer :: arg_bool
+ type(C_PTR), pointer :: arg_cptr
+ type(C_FUNPTR), pointer :: arg_cfunptr
+ type(s), pointer :: arg_struct
+ end subroutine
+
+ end interface
+
+ integer(C_INT), pointer :: var_int
+ integer(C_SHORT), pointer :: var_short
+ integer(C_LONG), pointer :: var_long
+ integer(C_LONG_LONG), pointer :: var_long_long
+ integer(C_SIGNED_CHAR), pointer :: var_signed_char
+ integer(C_INT8_T), pointer :: var_int8
+ integer(C_INT16_T), pointer :: var_int16
+ integer(C_INT32_T), pointer :: var_int32
+ integer(C_INT64_T), pointer :: var_int64
+ integer(C_INT_LEAST8_T), pointer :: var_least8
+ integer(C_INT_LEAST16_T), pointer :: var_least16
+ integer(C_INT_LEAST32_T), pointer :: var_least32
+ integer(C_INT_LEAST64_T), pointer :: var_least64
+ integer(C_INT_FAST8_T), pointer :: var_fast8
+ integer(C_INT_FAST16_T), pointer :: var_fast16
+ integer(C_INT_FAST32_T), pointer :: var_fast32
+ integer(C_INT_FAST64_T), pointer :: var_fast64
+ integer(C_SIZE_T), pointer :: var_size
+ integer(C_INTMAX_T), pointer :: var_intmax
+ integer(C_INTPTR_T), pointer :: var_intptr
+ integer(C_PTRDIFF_T), pointer :: var_ptrdiff
+ real(C_FLOAT), pointer :: var_float
+ real(C_DOUBLE), pointer :: var_double
+ complex(C_FLOAT_COMPLEX), pointer :: var_float_complex
+ complex(C_DOUBLE_COMPLEX), pointer :: var_double_complex
+ logical(C_BOOL), pointer :: var_bool
+ type(C_PTR), pointer :: var_cptr
+ type(C_FUNPTR), pointer :: var_cfunptr
+ type(s), pointer :: var_struct
+
+ nullify (var_int, var_short, var_long, var_long_long, var_signed_char)
+ call ctest_int1 (var_int, var_short, var_long, var_long_long, &
+ var_signed_char)
+
+ nullify (var_int8, var_int16, var_int32, var_int64)
+ call ctest_int2 (var_int8, var_int16, var_int32, var_int64)
+
+ nullify (var_least8, var_least16, var_least32, var_least64)
+ call ctest_int3 (var_least8, var_least16, var_least32, var_least64)
+
+ nullify (var_fast8, var_fast16, var_fast32, var_fast64)
+ call ctest_int4 (var_fast8, var_fast16, var_fast32, var_fast64)
+
+ nullify (var_size, var_intmax, var_intptr, var_ptrdiff)
+ call ctest_int5 (var_size, var_intmax, var_intptr, var_ptrdiff)
+
+ nullify (var_float, var_double)
+ call ctest_real (var_float, var_double)
+
+ nullify (var_float_complex, var_double_complex)
+ call ctest_complex (var_float_complex, var_double_complex)
+
+ nullify (var_bool, var_cptr, var_cfunptr, var_struct)
+ call ctest_misc (var_bool, var_cptr, var_cfunptr, var_struct)
+
+ ! FIXME: how do you pass something that corresponds to CFI_type_other?
+ ! The Fortran front end complains if you try to pass something that
+ ! isn't interoperable, such as a derived type object without bind(c).
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-scalar-float128-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-scalar-float128-c.c
@@ -0,0 +1,38 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *arg_float128,
+ CFI_cdesc_t *arg_complex128);
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_pointer)
+ abort ();
+ if (a->base_addr != NULL)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+void
+ctest (CFI_cdesc_t *arg_float128,
+ CFI_cdesc_t *arg_complex128)
+{
+ check (arg_float128, sizeof (_Float128), CFI_type_float128);
+ check (arg_complex128, sizeof (_Float128) * 2,
+ CFI_type_float128_Complex);
+}
+
Index: Fortran/gfortran/regression/c-interop/typecodes-scalar-float128.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-scalar-float128.f90
@@ -0,0 +1,34 @@
+! xfailed due to PR 101308
+! PR 101305
+! PR 100914
+! { dg-do run }
+! { dg-require-effective-target fortran_real_c_float128 }
+! { dg-additional-sources "typecodes-scalar-float128-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that the vendor extension kind constants provided by
+! gfortran's ISO_C_BINDING module result in the right type field in
+! arguments passed by descriptor,also matching the size of the corresponding
+! C type. We use pointers to force the use of a descriptor.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+
+ subroutine ctest (arg_float128, arg_complex128) bind (c)
+ use iso_c_binding
+ real(C_FLOAT128), pointer :: arg_float128
+ complex(C_FLOAT128_COMPLEX), pointer :: arg_complex128
+ end subroutine
+
+ end interface
+
+ real(C_FLOAT128), pointer :: var_float128
+ complex(C_FLOAT128_COMPLEX), pointer :: var_complex128
+
+ nullify (var_float128, var_complex128)
+ call ctest (var_float128, var_complex128)
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-scalar-int128-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-scalar-int128-c.c
@@ -0,0 +1,41 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *arg_int128,
+ CFI_cdesc_t *arg_least128,
+ CFI_cdesc_t *arg_fast128);
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_pointer)
+ abort ();
+ if (a->base_addr != NULL)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+void
+ctest (CFI_cdesc_t *arg_int128,
+ CFI_cdesc_t *arg_least128,
+ CFI_cdesc_t *arg_fast128)
+{
+ check (arg_int128, sizeof (__int128), CFI_type_int128_t);
+ check (arg_least128, sizeof (__int128), CFI_type_int_least128_t);
+ check (arg_fast128, sizeof (__int128), CFI_type_int_fast128_t);
+}
+
+
Index: Fortran/gfortran/regression/c-interop/typecodes-scalar-int128.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-scalar-int128.f90
@@ -0,0 +1,35 @@
+! PR 101305
+! xfailed due to PR 101308
+! { dg-do run }
+! { dg-require-effective-target fortran_integer_16 }
+! { dg-additional-sources "typecodes-scalar-int128-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that 128-bit integer kind constants provided by
+! gfortran's ISO_C_BINDING module result in the right type field in
+! arguments passed by descriptor, also matching the size of the corresponding
+! C type. We use pointers to force the use of a descriptor.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+
+ subroutine ctest (arg_int128, arg_least128, arg_fast128) bind (c)
+ use iso_c_binding
+ integer(C_INT128_T), pointer :: arg_int128
+ integer(C_INT_LEAST128_T), pointer :: arg_least128
+ integer(C_INT_FAST128_T), pointer :: arg_fast128
+ end subroutine
+
+ end interface
+
+ integer(C_INT128_T), pointer :: var_int128
+ integer(C_INT_LEAST128_T), pointer :: var_least128
+ integer(C_INT_FAST128_T), pointer :: var_fast128
+
+ nullify (var_int128, var_least128, var_fast128)
+ call ctest (var_int128, var_least128, var_fast128)
+
+end program
Index: Fortran/gfortran/regression/c-interop/typecodes-scalar-longdouble-c.c
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-scalar-longdouble-c.c
@@ -0,0 +1,37 @@
+#include
+#include
+#include
+#include
+
+#include
+#include "dump-descriptors.h"
+
+extern void ctest (CFI_cdesc_t *arg_long_double,
+ CFI_cdesc_t *arg_long_double_complex);
+
+/* Sanity check the type info in the descriptor a. */
+
+static void
+check (CFI_cdesc_t *a, size_t size, int typecode)
+{
+ dump_CFI_cdesc_t (a);
+ if (a->attribute != CFI_attribute_pointer)
+ abort ();
+ if (a->base_addr != NULL)
+ abort ();
+ if (a->rank != 0)
+ abort ();
+ if (size && a->elem_len != size)
+ abort ();
+ if (a->type != typecode)
+ abort ();
+}
+
+void
+ctest (CFI_cdesc_t *arg_long_double,
+ CFI_cdesc_t *arg_long_double_complex)
+{
+ check (arg_long_double, sizeof (long double), CFI_type_long_double);
+ check (arg_long_double_complex, sizeof (long double _Complex),
+ CFI_type_long_double_Complex);
+}
Index: Fortran/gfortran/regression/c-interop/typecodes-scalar-longdouble.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/typecodes-scalar-longdouble.f90
@@ -0,0 +1,33 @@
+! xfailed due to PR 101308
+! PR 101305
+! PR 100917
+! { dg-do run }
+! { dg-additional-sources "typecodes-scalar-longdouble-c.c dump-descriptors.c" }
+! { dg-additional-options "-g" }
+!
+! This program tests that long double kind constants in the ISO_C_BINDING
+! module result in the right type field in arguments passed by descriptor,
+! also matching the size of the corresponding C type. We use pointers
+! to force the use of a descriptor.
+
+program testit
+ use iso_c_binding
+ implicit none
+
+ interface
+
+ subroutine ctest (arg_long_double, arg_long_double_complex) bind (c)
+ use iso_c_binding
+ real(C_LONG_DOUBLE), pointer :: arg_long_double
+ complex(C_LONG_DOUBLE_COMPLEX), pointer :: arg_long_double_complex
+ end subroutine
+
+ end interface
+
+ real(C_LONG_DOUBLE), pointer :: var_long_double
+ complex(C_LONG_DOUBLE_COMPLEX), pointer :: var_long_double_complex
+
+ nullify (var_long_double, var_long_double_complex)
+ call ctest (var_long_double, var_long_double_complex)
+
+end program
Index: Fortran/gfortran/regression/c-interop/ubound-bindc.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ubound-bindc.f90
@@ -0,0 +1,129 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.4.3 UBOUND
+!
+! The description of the intrinsic function UBOUND in ISO/IEC
+! 1539-1:2010 is changed for an assumed-rank object that is associated
+! with an assumed-size array; the result of UBOUND (ARRAY, RANK(ARRAY),
+! KIND) has a value equal to LBOUND (ARRAY, RANK (ARRAY), KIND) −2 with
+! KIND omitted from LBOUND if it was omitted from UBOUND.
+!
+! NOTE 6.2
+! If LBOUND or UBOUND is invoked for an assumed-rank object that is
+! associated with a scalar and DIM is absent, the result is a zero-sized
+! array. LBOUND or UBOUND cannot be invoked for an assumed-rank object
+! that is associated with a scalar if DIM is present because the rank of
+! a scalar is zero and DIM must be ≥ 1.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+
+program test
+
+ ! Define some arrays for testing.
+ integer, target :: x1(5)
+ integer :: y1(0:9)
+ integer, pointer :: p1(:)
+ integer, allocatable :: a1(:)
+ integer, target :: x3(2,3,4)
+ integer :: y3(0:1,-3:-1,4)
+ integer, pointer :: p3(:,:,:)
+ integer, allocatable :: a3(:,:,:)
+ integer :: x
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call testit2(x1, shape(x1))
+ call test1 (y1)
+ call testit2(y1, shape(y1))
+ p1 => x1
+ call testit2(p1, shape(p1))
+ call testit2p(p1, lbound(p1), shape(p1))
+ call test1 (p1)
+ p1(77:) => x1
+ call testit2p(p1, [77], shape(p1))
+ allocate (a1(5))
+ call testit2(a1, shape(a1))
+ call testit2a(a1, lbound(a1), shape(a1))
+ call test1 (a1)
+ deallocate(a1)
+ allocate (a1(-38:5))
+ call test1 (a1)
+ call testit2(a1, shape(a1))
+ call testit2a(a1, [-38], shape(a1))
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+ ! Test some scalars.
+ call test0 (x)
+ call test0 (-1)
+ call test0 (x1(1))
+
+contains
+
+ subroutine testit (a) bind(c)
+ integer :: a(..)
+ integer :: r
+ r = rank(a)
+ if (any (lbound (a) .ne. 1)) stop 101
+ if (ubound (a, r) .ne. -1) stop 102
+ end subroutine
+
+ subroutine testit2(a, shape) bind(c)
+ integer :: a(..)
+ integer :: shape(:)
+ if (rank(a) /= size(shape)) stop 111
+ if (any (lbound(a) /= 1)) stop 112
+ if (any (ubound(a) /= shape)) stop 113
+ end subroutine
+
+ subroutine testit2a(a,lbound2, shape2) bind(c)
+ integer, allocatable :: a(..)
+ integer :: lbound2(:), shape2(:)
+ if (rank(a) /= size(shape2)) stop 121
+ if (any (lbound(a) /= lbound2)) stop 122
+ if (any (ubound(a) /= lbound2 + shape2 - 1)) stop 123
+ if (any (shape(a) /= shape2)) stop 124
+ if (sum (shape(a)) /= size(a)) stop 125
+ end subroutine
+
+ subroutine testit2p(a, lbound2, shape2) bind(c)
+ integer, pointer :: a(..)
+ integer :: lbound2(:), shape2(:)
+ if (rank(a) /= size(shape2)) stop 131
+ if (any (lbound(a) /= lbound2)) stop 132
+ if (any (ubound(a) /= lbound2 + shape2 - 1)) stop 133
+ if (any (shape(a) /= shape2)) stop 134
+ if (sum (shape(a)) /= size(a)) stop 135
+ end subroutine
+
+ subroutine test0 (a) bind(c)
+ integer :: a(..)
+ if (rank (a) .ne. 0) stop 141
+ if (size (lbound (a)) .ne. 0) stop 142
+ if (size (ubound (a)) .ne. 0) stop 143
+ end subroutine
+
+ subroutine test1 (a) bind(c)
+ integer :: a(*)
+
+ call testit (a)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2) bind(c)
+ implicit none
+ integer :: l1, u1, l2, u2
+ integer :: a(l1:u1, l2:u2, *)
+
+ call testit (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/ubound-poly.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ubound-poly.f90
@@ -0,0 +1,145 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.4.3 UBOUND
+!
+! The description of the intrinsic function UBOUND in ISO/IEC
+! 1539-1:2010 is changed for an assumed-rank object that is associated
+! with an assumed-size array; the result of UBOUND (ARRAY, RANK(ARRAY),
+! KIND) has a value equal to LBOUND (ARRAY, RANK (ARRAY), KIND) −2 with
+! KIND omitted from LBOUND if it was omitted from UBOUND.
+!
+! NOTE 6.2
+! If LBOUND or UBOUND is invoked for an assumed-rank object that is
+! associated with a scalar and DIM is absent, the result is a zero-sized
+! array. LBOUND or UBOUND cannot be invoked for an assumed-rank object
+! that is associated with a scalar if DIM is present because the rank of
+! a scalar is zero and DIM must be ≥ 1.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+!
+! This is like ubound.f90, but using polymorphic arrays instead of integer
+! arrays.
+
+module m
+ type :: t
+ integer :: id
+ real :: xyz(3)
+ end type
+end module
+
+program test
+ use m
+
+ ! Define some arrays for testing.
+ type(t), target :: x1(5)
+ type(t) :: y1(0:9)
+ class(t), pointer :: p1(:)
+ class(t), allocatable :: a1(:)
+ type(t), target :: x3(2,3,4)
+ type(t) :: y3(0:1,-3:-1,4)
+ class(t), pointer :: p3(:,:,:)
+ type(t), allocatable :: a3(:,:,:)
+ type(t) :: x
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call testit2(x1, shape(x1))
+ call test1 (y1)
+ call testit2(y1, shape(y1))
+ p1 => x1
+ call testit2(p1, shape(p1))
+ call testit2p(p1, lbound(p1), shape(p1))
+ call test1 (p1)
+ p1(77:) => x1
+ call testit2p(p1, [77], shape(p1))
+ allocate (a1(5))
+ call testit2(a1, shape(a1))
+ call testit2a(a1, lbound(a1), shape(a1))
+ call test1 (a1)
+ deallocate(a1)
+ allocate (a1(-38:5))
+ call test1 (a1)
+ call testit2(a1, shape(a1))
+ call testit2a(a1, [-38], shape(a1))
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+ ! Test some scalars.
+ call test0 (x)
+ call test0 (x1(1))
+
+contains
+
+ subroutine testit (a)
+ use m
+ class(t) :: a(..)
+ integer :: r
+ r = rank(a)
+ if (any (lbound (a) .ne. 1)) stop 101
+ if (ubound (a, r) .ne. -1) stop 102
+ end subroutine
+
+ subroutine testit2(a, shape)
+ use m
+ class(t) :: a(..)
+ integer :: shape(:)
+ if (rank(a) /= size(shape)) stop 111
+ if (any (lbound(a) /= 1)) stop 112
+ if (any (ubound(a) /= shape)) stop 113
+ end subroutine
+
+ subroutine testit2a(a,lbound2, shape2)
+ use m
+ class(t), allocatable :: a(..)
+ integer :: lbound2(:), shape2(:)
+ if (rank(a) /= size(shape2)) stop 121
+ if (any (lbound(a) /= lbound2)) stop 122
+ if (any (ubound(a) /= lbound2 + shape2 - 1)) stop 123
+ if (any (shape(a) /= shape2)) stop 124
+ if (sum (shape(a)) /= size(a)) stop 125
+ end subroutine
+
+ subroutine testit2p(a, lbound2, shape2)
+ use m
+ class(t), pointer :: a(..)
+ integer :: lbound2(:), shape2(:)
+ if (rank(a) /= size(shape2)) stop 131
+ if (any (lbound(a) /= lbound2)) stop 132
+ if (any (ubound(a) /= lbound2 + shape2 - 1)) stop 133
+ if (any (shape(a) /= shape2)) stop 134
+ if (sum (shape(a)) /= size(a)) stop 135
+ end subroutine
+
+ subroutine test0 (a)
+ use m
+ class(t) :: a(..)
+ if (rank (a) .ne. 0) stop 141
+ if (size (lbound (a)) .ne. 0) stop 142
+ if (size (ubound (a)) .ne. 0) stop 143
+ end subroutine
+
+ subroutine test1 (a)
+ use m
+ class(t) :: a(*)
+
+ call testit (a)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2)
+ use m
+ integer :: l1, u1, l2, u2
+ class(t) :: a(l1:u1, l2:u2, *)
+
+ call testit (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/c-interop/ubound.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/c-interop/ubound.f90
@@ -0,0 +1,129 @@
+! { dg-do run }
+!
+! TS 29113
+! 6.4.3 UBOUND
+!
+! The description of the intrinsic function UBOUND in ISO/IEC
+! 1539-1:2010 is changed for an assumed-rank object that is associated
+! with an assumed-size array; the result of UBOUND (ARRAY, RANK(ARRAY),
+! KIND) has a value equal to LBOUND (ARRAY, RANK (ARRAY), KIND) −2 with
+! KIND omitted from LBOUND if it was omitted from UBOUND.
+!
+! NOTE 6.2
+! If LBOUND or UBOUND is invoked for an assumed-rank object that is
+! associated with a scalar and DIM is absent, the result is a zero-sized
+! array. LBOUND or UBOUND cannot be invoked for an assumed-rank object
+! that is associated with a scalar if DIM is present because the rank of
+! a scalar is zero and DIM must be ≥ 1.
+!
+! The idea here is that the main program passes some arrays to a test
+! subroutine with an assumed-size dummy, which in turn passes that to a
+! subroutine with an assumed-rank dummy.
+
+program test
+
+ ! Define some arrays for testing.
+ integer, target :: x1(5)
+ integer :: y1(0:9)
+ integer, pointer :: p1(:)
+ integer, allocatable :: a1(:)
+ integer, target :: x3(2,3,4)
+ integer :: y3(0:1,-3:-1,4)
+ integer, pointer :: p3(:,:,:)
+ integer, allocatable :: a3(:,:,:)
+ integer :: x
+
+ ! Test the 1-dimensional arrays.
+ call test1 (x1)
+ call testit2(x1, shape(x1))
+ call test1 (y1)
+ call testit2(y1, shape(y1))
+ p1 => x1
+ call testit2(p1, shape(p1))
+ call testit2p(p1, lbound(p1), shape(p1))
+ call test1 (p1)
+ p1(77:) => x1
+ call testit2p(p1, [77], shape(p1))
+ allocate (a1(5))
+ call testit2(a1, shape(a1))
+ call testit2a(a1, lbound(a1), shape(a1))
+ call test1 (a1)
+ deallocate(a1)
+ allocate (a1(-38:5))
+ call test1 (a1)
+ call testit2(a1, shape(a1))
+ call testit2a(a1, [-38], shape(a1))
+
+ ! Test the multi-dimensional arrays.
+ call test3 (x3, 1, 2, 1, 3)
+ call test3 (y3, 0, 1, -3, -1)
+ p3 => x3
+ call test3 (p3, 1, 2, 1, 3)
+ allocate (a3(2,3,4))
+ call test3 (a3, 1, 2, 1, 3)
+
+ ! Test some scalars.
+ call test0 (x)
+ call test0 (-1)
+ call test0 (x1(1))
+
+contains
+
+ subroutine testit (a)
+ integer :: a(..)
+ integer :: r
+ r = rank(a)
+ if (any (lbound (a) .ne. 1)) stop 101
+ if (ubound (a, r) .ne. -1) stop 102
+ end subroutine
+
+ subroutine testit2(a, shape)
+ integer :: a(..)
+ integer :: shape(:)
+ if (rank(a) /= size(shape)) stop 111
+ if (any (lbound(a) /= 1)) stop 112
+ if (any (ubound(a) /= shape)) stop 113
+ end subroutine
+
+ subroutine testit2a(a,lbound2, shape2)
+ integer, allocatable :: a(..)
+ integer :: lbound2(:), shape2(:)
+ if (rank(a) /= size(shape2)) stop 121
+ if (any (lbound(a) /= lbound2)) stop 122
+ if (any (ubound(a) /= lbound2 + shape2 - 1)) stop 123
+ if (any (shape(a) /= shape2)) stop 124
+ if (sum (shape(a)) /= size(a)) stop 125
+ end subroutine
+
+ subroutine testit2p(a, lbound2, shape2)
+ integer, pointer :: a(..)
+ integer :: lbound2(:), shape2(:)
+ if (rank(a) /= size(shape2)) stop 131
+ if (any (lbound(a) /= lbound2)) stop 132
+ if (any (ubound(a) /= lbound2 + shape2 - 1)) stop 133
+ if (any (shape(a) /= shape2)) stop 134
+ if (sum (shape(a)) /= size(a)) stop 135
+ end subroutine
+
+ subroutine test0 (a)
+ integer :: a(..)
+ if (rank (a) .ne. 0) stop 141
+ if (size (lbound (a)) .ne. 0) stop 142
+ if (size (ubound (a)) .ne. 0) stop 143
+ end subroutine
+
+ subroutine test1 (a)
+ integer :: a(*)
+
+ call testit (a)
+ end subroutine
+
+ subroutine test3 (a, l1, u1, l2, u2)
+ implicit none
+ integer :: l1, u1, l2, u2
+ integer :: a(l1:u1, l2:u2, *)
+
+ call testit (a)
+ end subroutine
+
+end program
Index: Fortran/gfortran/regression/coarray/alloc_comp_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/alloc_comp_1.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+!
+! Allocatable scalar corrays were mishandled (ICE)
+!
+type t
+ integer, allocatable :: caf[:]
+end type t
+type(t) :: a
+allocate (a%caf[3:*])
+a%caf = 7
+if (a%caf /= 7) STOP 1
+if (any (lcobound (a%caf) /= [ 3 ]) &
+ .or. ucobound (a%caf, dim=1) /= num_images ()+2) &
+ STOP 2
+deallocate (a%caf)
+end
Index: Fortran/gfortran/regression/coarray/alloc_comp_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/alloc_comp_2.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+!
+! PR fortran/56929
+!
+! Contributed by Damian Rouson
+!
+! Allocatable scalar corrays were mishandled (ICE)
+!
+module parent_coarray_component
+ type parent
+ real, allocatable :: dummy[:]
+ end type
+ type, extends(parent) :: child
+ end type
+contains
+ subroutine do_something(this)
+ class(child) this
+ end
+end
Index: Fortran/gfortran/regression/coarray/alloc_comp_3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/alloc_comp_3.f90
@@ -0,0 +1,23 @@
+! { dg-do compile }
+!
+! PR fortran/60881
+!
+! Contributed by Damian Rouson
+!
+! Was ICEing before
+!
+program main
+ implicit none
+ type co_object
+ logical :: defined=.false.
+ real, allocatable :: dummy_to_facilitate_extension[:]
+ end type
+ type, extends(co_object) :: global_field
+ end type
+ type(global_field) T
+ call assign_local_field(T)
+contains
+ subroutine assign_local_field(lhs)
+ type(global_field) lhs
+ end subroutine
+end program
Index: Fortran/gfortran/regression/coarray/alloc_comp_4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/alloc_comp_4.f90
@@ -0,0 +1,21 @@
+! { dg-do run }
+
+! Contributed by Damian Rouson
+
+program main
+
+ implicit none
+
+ type mytype
+ integer, allocatable :: indices(:)
+ end type
+
+ type(mytype), save :: object[*]
+ integer :: me
+
+ me=this_image()
+ allocate(object%indices(me))
+ object%indices = 42
+
+ if ( any( object[me]%indices(:) /= 42 ) ) STOP 1
+end program
Index: Fortran/gfortran/regression/coarray/alloc_comp_5.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/alloc_comp_5.f90
@@ -0,0 +1,17 @@
+! { dg-do run }
+
+program Jac
+ type Domain
+ integer :: n=64
+ integer,allocatable :: endsi(:)
+ end type
+ type(Domain),allocatable :: D[:,:,:]
+
+ allocate(D[2,2,*])
+ allocate(D%endsi(2), source = 0)
+ ! No caf-runtime call needed her.
+ D%endsi(2) = D%n
+ if (any(D%endsi /= [ 0, 64])) error stop
+ deallocate(D)
+end program
+
Index: Fortran/gfortran/regression/coarray/allocate_errgmsg.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/allocate_errgmsg.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+!
+! Check handling of errmsg.
+!
+implicit none
+integer, allocatable :: a[:], b(:)[:], c, d(:)
+integer :: stat
+character(len=300) :: str
+
+allocate(a[*], b(1)[*], c, d(2), stat=stat)
+
+str = repeat('X', len(str))
+allocate(a[*], stat=stat, errmsg=str)
+!print *, stat, trim(str)
+if (stat == 0 .or. str /= "Attempt to allocate an allocated object") &
+ STOP 1
+
+str = repeat('Y', len(str))
+allocate(b(2)[*], stat=stat, errmsg=str)
+!print *, stat, trim(str)
+if (stat == 0 .or. str /= "Attempt to allocate an allocated object") &
+ STOP 2
+
+str = repeat('Q', len(str))
+allocate(c, stat=stat, errmsg=str)
+!print *, stat, trim(str)
+if (stat == 0 .or. str /= "Attempt to allocate an allocated object") &
+ STOP 3
+
+str = repeat('P', len(str))
+allocate(d(3), stat=stat, errmsg=str)
+!print *, stat, trim(str)
+if (stat == 0 .or. str /= "Attempt to allocate an allocated object") &
+ STOP 4
+
+end
Index: Fortran/gfortran/regression/coarray/array_temporary-1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/array_temporary-1.f90
@@ -0,0 +1,13 @@
+! PR fortran/99010
+!
+! Follow-up to PR fortran/98913
+!
+! Contributed by G. Steinmetz
+!
+program p
+ integer :: x[*]
+ x = this_image()
+ if ( this_image() == 2 ) then
+ x = x[1]
+ end if
+end
Index: Fortran/gfortran/regression/coarray/array_temporary.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/array_temporary.f90
@@ -0,0 +1,74 @@
+! { dg-do compile }
+! { dg-additional-options "-Warray-temporaries" }
+!
+! PR fortran/98913
+!
+! Contributed by Jorge D'Elia
+!
+! Did create an array temporary for local access to coarray
+! (but not for identical noncoarray use).
+!
+
+program test
+ implicit none
+ integer, parameter :: iin = kind (1)
+ integer, parameter :: idp = kind (1.0d0)
+ real (kind=idp), allocatable :: AA (:,:)[:]
+ real (kind=idp), allocatable :: BB (:,:)
+ real (kind=idp), allocatable :: UU (:)
+ integer (kind=iin) :: nn, n1, n2
+ integer (kind=iin) :: j, k, k1
+ !
+ nn = 5
+ n1 = 1
+ n2 = 10
+ !
+ allocate (AA (1:nn,n1:n2)[*])
+ allocate (BB (1:nn,n1:n2))
+ allocate (UU (1:nn))
+ !
+ k = 1
+ k1 = k + 1
+ !
+ AA = 1.0_idp
+ BB = 1.0_idp
+ UU = 2.0_idp
+
+ ! AA - coarrays
+ ! No temporary needed:
+ do j = 1, nn
+ AA (k1:nn,j) = AA (k1:nn,j) - UU (k1:nn) * AA (k,j) ! { dg-bogus "Creating array temporary" }
+ end do
+ do j = 1, nn
+ AA (k1:nn,j) = AA (k1:nn,j) - UU (k1:nn) * AA (k,j) - UU(k) * AA (k1-1:nn-1,j) ! { dg-bogus "Creating array temporary" }
+ end do
+ do j = 1, nn
+ AA (k1:nn,j) = AA (k1:nn,j) - UU (k1:nn) * AA (k,j) - UU(k) * AA (k1+1:nn+1,j) ! { dg-bogus "Creating array temporary" }
+ end do
+
+ ! But:
+ do j = 1, nn
+ AA (k1:nn,j) = AA (k1-1:nn-1,j) - UU (k1:nn) * AA (k,j) - UU(k) * AA (k1+1:nn+1,j) ! { dg-warning "Creating array temporary" }
+ end do
+
+ ! BB - no coarrays
+ ! No temporary needed:
+ do j = 1, nn
+ BB (k1:nn,j) = BB (k1:nn,j) - UU (k1:nn) * BB (k,j) ! { dg-bogus "Creating array temporary" }
+ end do
+ do j = 1, nn
+ BB (k1:nn,j) = BB (k1:nn,j) - UU (k1:nn) * BB (k,j) - UU(k) * BB (k1-1:nn-1,j) ! { dg-bogus "Creating array temporary" }
+ end do
+ do j = 1, nn
+ BB (k1:nn,j) = BB (k1:nn,j) - UU (k1:nn) * BB (k,j) - UU(k) * BB (k1+1:nn+1,j) ! { dg-bogus "Creating array temporary" }
+ end do
+
+ ! But:
+ do j = 1, nn
+ BB (k1:nn,j) = BB (k1-1:nn-1,j) - UU (k1:nn) * BB (k,j) - UU(k) * BB (k1+1:nn+1,j) ! { dg-warning "Creating array temporary" }
+ end do
+
+ deallocate (AA)
+ deallocate (BB)
+ deallocate (UU)
+end program test
Index: Fortran/gfortran/regression/coarray/atomic_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/atomic_1.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+!
+! PR fortran/18918
+!
+! Basic atomic def/ref test
+!
+
+use iso_fortran_env, only: atomic_int_kind, atomic_logical_kind
+implicit none
+integer(atomic_int_kind) :: a(1)[*]
+logical(atomic_logical_kind) :: c[*]
+intrinsic :: atomic_define
+intrinsic :: atomic_ref
+integer(8) :: b
+logical(1) :: d
+
+call atomic_define(a(1), 7_2)
+call atomic_ref(b, a(1))
+if (b /= a(1)) STOP 1
+
+call atomic_define(c, .false.)
+call atomic_ref(d, c[this_image()])
+if (d .neqv. .false.) STOP 2
+call atomic_define(c[this_image()], .true.)
+call atomic_ref(d, c)
+if (d .neqv. .true.) STOP 3
+end
Index: Fortran/gfortran/regression/coarray/atomic_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/atomic_2.f90
@@ -0,0 +1,653 @@
+! { dg-do run }
+!
+use iso_fortran_env, only: atomic_int_kind, atomic_logical_kind
+implicit none
+
+intrinsic :: atomic_define
+intrinsic :: atomic_ref
+intrinsic :: atomic_cas
+intrinsic :: atomic_add
+intrinsic :: atomic_and
+intrinsic :: atomic_or
+intrinsic :: atomic_xor
+intrinsic :: atomic_fetch_add
+intrinsic :: atomic_fetch_and
+intrinsic :: atomic_fetch_or
+intrinsic :: atomic_fetch_xor
+integer(atomic_int_kind) :: caf[*], var, var3
+logical(atomic_logical_kind) :: caf_log[*], var2
+integer :: stat, i
+
+caf = 0
+caf_log = .false.
+sync all
+
+if (this_image() == 1) then
+ call atomic_define(caf[num_images()], 5, stat=stat)
+ if (stat /= 0) STOP 1
+ call atomic_define(caf_log[num_images()], .true., stat=stat)
+ if (stat /= 0) STOP 2
+end if
+sync all
+
+if (this_image() == num_images()) then
+ if (caf /= 5) STOP 3
+ if (.not. caf_log) STOP 4
+ var = 99
+ call atomic_ref(var, caf, stat=stat)
+ if (stat /= 0 .or. var /= 5) STOP 5
+ var2 = .false.
+ call atomic_ref(var2, caf_log, stat=stat)
+ if (stat /= 0 .or. .not. var2) STOP 6
+end if
+call atomic_ref(var, caf[num_images()], stat=stat)
+if (stat /= 0 .or. var /= 5) STOP 7
+call atomic_ref(var2, caf_log[num_images()], stat=stat)
+if (stat /= 0 .or. .not. var2) STOP 8
+sync all
+
+! ADD
+caf = 0
+sync all
+
+call atomic_add(caf, this_image(), stat=stat)
+if (stat /= 0) STOP 9
+do i = 1, num_images()
+ call atomic_add(caf[i], 1, stat=stat)
+ if (stat /= 0) STOP 10
+ call atomic_ref(var, caf, stat=stat)
+ if (stat /= 0 .or. var < this_image()) STOP 11
+end do
+sync all
+
+call atomic_ref(var, caf[num_images()], stat=stat)
+if (stat /= 0 .or. var /= num_images() + this_image()) STOP 12
+do i = 1, num_images()
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= num_images() + i) STOP 13
+end do
+sync all
+
+! AND(1)
+caf = 0
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_and(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 14
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = 0
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = iand(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 15
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 16
+ end if
+ end do
+end if
+sync all
+
+! AND(2)
+caf = -1
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_and(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 17
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = -1
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = iand(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 18
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 19
+ end if
+ end do
+end if
+sync all
+
+! AND(3)
+caf = 0
+do i = 1, storage_size(caf)-2, 2
+ caf = shiftl(1, i)
+ var3 = shiftl(1, i)
+end do
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_and(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 20
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = iand(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 21
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 22
+ end if
+ end do
+end if
+sync all
+
+! OR(1)
+caf = 0
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_or(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 23
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = 0
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ior(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 24
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 25
+ end if
+ end do
+end if
+sync all
+
+! OR(2)
+caf = -1
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_or(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 26
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = -1
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ior(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 27
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 28
+ end if
+ end do
+end if
+sync all
+
+! OR(3)
+caf = 0
+do i = 1, storage_size(caf)-2, 2
+ caf = shiftl(1, i)
+ var3 = shiftl(1, i)
+end do
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_or(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 29
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ior(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 30
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 31
+ end if
+ end do
+end if
+sync all
+
+! XOR(1)
+caf = 0
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_xor(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 32
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = 0
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ieor(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 33
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 34
+ end if
+ end do
+end if
+sync all
+
+! XOR(2)
+caf = -1
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_xor(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 35
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = -1
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ieor(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 36
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 37
+ end if
+ end do
+end if
+sync all
+
+! XOR(3)
+caf = 0
+do i = 1, storage_size(caf)-2, 2
+ caf = shiftl(1, i)
+ var3 = shiftl(1, i)
+end do
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ call atomic_xor(caf[i], shiftl(1, this_image()), stat=stat)
+ if (stat /= 0) STOP 38
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ieor(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 39
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 40
+ end if
+ end do
+end if
+sync all
+
+! ADD
+caf = 0
+sync all
+var = -99
+call atomic_fetch_add(caf, this_image(), var, stat=stat)
+if (stat /= 0 .or. var < 0) STOP 41
+if (num_images() == 1 .and. var /= 0) STOP 42
+do i = 1, num_images()
+ var = -99
+ call atomic_fetch_add(caf[i], 1, var, stat=stat)
+ if (stat /= 0 .or. var < 0) STOP 43
+ call atomic_ref(var, caf, stat=stat)
+ if (stat /= 0 .or. var < this_image()) STOP 44
+end do
+sync all
+
+call atomic_ref(var, caf[num_images()], stat=stat)
+if (stat /= 0 .or. var /= num_images() + this_image()) STOP 45
+do i = 1, num_images()
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= num_images() + i) STOP 46
+end do
+sync all
+
+
+! AND(1)
+caf = 0
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = 99
+ call atomic_fetch_and(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. var /= 0) STOP 47
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = 0
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = iand(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 48
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 49
+ end if
+ end do
+end if
+sync all
+
+! AND(2)
+caf = -1
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = -99
+ call atomic_fetch_and(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. var == shiftl(1, this_image())) STOP 50
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = -1
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = iand(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 51
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 52
+ end if
+ end do
+end if
+sync all
+
+! AND(3)
+caf = 0
+var3 = 0
+do i = 1, storage_size(caf)-2, 2
+ caf = ior(shiftl(1, i), caf)
+ var3 = ior(shiftl(1, i), var3)
+end do
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = -99
+ call atomic_fetch_and(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. var <= 0) STOP 53
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = iand(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 54
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 55
+ end if
+ end do
+end if
+sync all
+
+
+
+! OR(1)
+caf = 0
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = -99
+ call atomic_fetch_or(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. var < 0 .or. var == shiftl(1, this_image())) STOP 56
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = 0
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ior(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 57
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 58
+ end if
+ end do
+end if
+sync all
+
+! OR(2)
+caf = -1
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = -99
+ call atomic_fetch_or(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. (var < 0 .and. var /= -1)) STOP 59
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = -1
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ior(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 60
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 61
+ end if
+ end do
+end if
+sync all
+
+! OR(3)
+caf = 0
+var3 = 0
+do i = 1, storage_size(caf)-2, 2
+ caf = ior(shiftl(1, i), caf)
+ var3 = ior(shiftl(1, i), var3)
+end do
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = -99
+ call atomic_fetch_or(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. var <= 0) STOP 62
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ior(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 63
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 64
+ end if
+ end do
+end if
+sync all
+
+
+! XOR(1)
+caf = 0
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = -99
+ call atomic_fetch_xor(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. var < 0 .or. var == shiftl(1, this_image())) STOP 65
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = 0
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ieor(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 66
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 67
+ end if
+ end do
+end if
+sync all
+
+! XOR(2)
+caf = -1
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = -99
+ call atomic_fetch_xor(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. (var < 0 .and. var /= -1)) STOP 68
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ var3 = -1
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ieor(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 69
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 70
+ end if
+ end do
+end if
+sync all
+
+! XOR(3)
+caf = 0
+var3 = 0
+do i = 1, storage_size(caf)-2, 2
+ caf = ior(shiftl(1, i), caf)
+ var3 = ior(shiftl(1, i), var3)
+end do
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = this_image(), min(num_images(), storage_size(caf)-2)
+ var = -99
+ call atomic_fetch_xor(caf[i], shiftl(1, this_image()), var, stat=stat)
+ if (stat /= 0 .or. var <= 0) STOP 71
+ end do
+end if
+sync all
+
+if (this_image() < storage_size(caf)-2) then
+ do i = 1, min(num_images(), storage_size(caf)-2)
+ var3 = ieor(var3, shiftl(1, i))
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 72
+ if (i == this_image()) then
+ call atomic_ref(var, caf[i], stat=stat)
+ if (stat /= 0 .or. var /= var3) STOP 73
+ end if
+ end do
+end if
+sync all
+
+! CAS
+caf = 9
+caf_log = .true.
+sync all
+
+if (this_image() == 1) then
+ call atomic_cas(caf[num_images()], compare=5, new=3, old=var, stat=stat)
+ if (stat /= 0 .or. var /= 9) STOP 74
+ call atomic_ref(var, caf[num_images()], stat=stat)
+ if (stat /= 0 .or. var /= 9) STOP 75
+end if
+sync all
+
+if (this_image() == num_images() .and. caf /= 9) STOP 76
+call atomic_ref(var, caf[num_images()], stat=stat)
+if (stat /= 0 .or. var /= 9) STOP 77
+sync all
+
+if (this_image() == 1) then
+ call atomic_cas(caf[num_images()], compare=9, new=3, old=var, stat=stat)
+ if (stat /= 0 .or. var /= 9) STOP 78
+ call atomic_ref(var, caf[num_images()], stat=stat)
+ if (stat /= 0 .or. var /= 3) STOP 79
+end if
+sync all
+
+if (this_image() == num_images() .and. caf /= 3) STOP 80
+call atomic_ref(var, caf[num_images()], stat=stat)
+if (stat /= 0 .or. var /= 3) STOP 81
+sync all
+
+
+if (this_image() == 1) then
+ call atomic_cas(caf_log[num_images()], compare=.false., new=.false., old=var2, stat=stat)
+ if (stat /= 0 .or. var2 .neqv. .true.) STOP 82
+ call atomic_ref(var2, caf_log[num_images()], stat=stat)
+ if (stat /= 0 .or. var2 .neqv. .true.) STOP 83
+end if
+sync all
+
+if (this_image() == num_images() .and. caf_log .neqv. .true.) STOP 84
+call atomic_ref(var2, caf_log[num_images()], stat=stat)
+if (stat /= 0 .or. var2 .neqv. .true.) STOP 85
+sync all
+
+if (this_image() == 1) then
+ call atomic_cas(caf_log[num_images()], compare=.true., new=.false., old=var2, stat=stat)
+ if (stat /= 0 .or. var2 .neqv. .true.) STOP 86
+ call atomic_ref(var2, caf_log[num_images()], stat=stat)
+ if (stat /= 0 .or. var2 .neqv. .false.) STOP 87
+end if
+sync all
+
+if (this_image() == num_images() .and. caf_log .neqv. .false.) STOP 88
+call atomic_ref(var2, caf_log[num_images()], stat=stat)
+if (stat /= 0 .or. var2 .neqv. .false.) STOP 89
+end
Index: Fortran/gfortran/regression/coarray/caf.exp
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/caf.exp
@@ -0,0 +1,112 @@
+# Copyright (C) 2011-2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# .
+#
+# Contributed by Tobias Burnus
+
+
+# Test coarray support.
+#
+# For the compilation tests, all files are compiles with the
+# option -fcoarray=single and with -fcoarray=lib
+#
+# For the link and execution tests, for -fcoarray=lib the
+# libcaf_single library is linked. Additionally, with the
+# required settings another CAF library is used.
+
+# Load procedures from common libraries.
+load_lib gfortran-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_FFLAGS
+if ![info exists DEFAULT_FFLAGS] then {
+ set DEFAULT_FFLAGS " -pedantic-errors"
+}
+
+dg-init
+
+global runtests
+global DG_TORTURE_OPTIONS torture_with_loops
+
+torture-init
+set-torture-options $DG_TORTURE_OPTIONS
+
+global gfortran_test_path
+global gfortran_aux_module_flags
+set gfortran_test_path $srcdir/$subdir
+set gfortran_aux_module_flags $DEFAULT_FFLAGS
+proc dg-compile-aux-modules { args } {
+ global gfortran_test_path
+ global gfortran_aux_module_flags
+ if { [llength $args] != 2 } {
+ error "dg-compile-aux-modules: needs one argument"
+ return
+ }
+
+ set level [info level]
+ if { [info procs dg-save-unknown] != [list] } {
+ rename dg-save-unknown dg-save-unknown-level-$level
+ }
+
+ dg-test $gfortran_test_path/[lindex $args 1] "" $gfortran_aux_module_flags
+ # cleanup-modules is intentionally not invoked here.
+
+ if { [info procs dg-save-unknown-level-$level] != [list] } {
+ rename dg-save-unknown-level-$level dg-save-unknown
+ }
+}
+
+# Add -latomic only where supported. Assume built-in support elsewhere.
+set maybe_atomic_lib ""
+if [check_effective_target_libatomic_available] {
+ set maybe_atomic_lib "-latomic"
+}
+
+# Main loop.
+foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.\[fF\]{,90,95,03,08} ]] {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $test] then {
+ continue
+ }
+
+# Enable if you want to test several options:
+# # look if this is dg-do-run test, in which case
+# # we cycle through the option list, otherwise we don't
+# if [expr [search_for $test "dg-do run"]] {
+# set option_list $torture_with_loops
+# } else {
+# set option_list [list { -O } ]
+# }
+ set option_list [list { -O2 } ]
+
+ set nshort [file tail [file dirname $test]]/[file tail $test]
+ list-module-names $test
+
+ foreach flags $option_list {
+ verbose "Testing $nshort (single), $flags" 1
+ set gfortran_aux_module_flags "-fcoarray=single $flags"
+ dg-test $test "-fcoarray=single $flags $maybe_atomic_lib" ""
+ cleanup-modules ""
+ }
+
+ foreach flags $option_list {
+ verbose "Testing $nshort (libcaf_single), $flags" 1
+ set gfortran_aux_module_flags "-fcoarray=lib $flags -lcaf_single"
+ dg-test $test "-fcoarray=lib $flags -lcaf_single $maybe_atomic_lib" ""
+ cleanup-modules ""
+ }
+}
+torture-finish
+dg-finish
Index: Fortran/gfortran/regression/coarray/coarray_allocated.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/coarray_allocated.f90
@@ -0,0 +1,55 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original" }
+! PR fortran/93834 - ICE in trans_caf_is_present
+
+program p
+ type t
+ integer, allocatable :: x[:,:,:]
+ end type t
+ integer, allocatable :: a[:]
+ type(t) :: c
+ if (allocated (a)) stop 1
+ if (allocated (c%x)) stop 2
+
+ ! The coindexed scalar (!) variable is regarded as allocatable but
+ ! we can check the value on any image of the team as they are
+ ! established collectively. As tested by the dump, we do it on
+ ! this_image ().
+ !
+ ! For this reason, -fcoarray=single and -fcoarray=lib give the
+ ! same result
+ if (allocated (a[1])) stop 3
+ if (allocated (c%x[1,2,3])) stop 4
+
+ ! Allocate collectively
+ allocate(a[*])
+ allocate(c%x[4,10,*])
+
+ if (.not. allocated (a)) stop 5
+ if (.not. allocated (c%x)) stop 6
+ if (.not. allocated (a[1])) stop 7
+ if (.not. allocated (c%x[1,2,3])) stop 8
+
+ ! Dellocate collectively
+ deallocate(a)
+ deallocate(c%x)
+
+ if (allocated (a)) stop 9
+ if (allocated (c%x)) stop 10
+ if (allocated (a[1])) stop 11
+ if (allocated (c%x[1,2,3])) stop 12
+end
+
+! twice == 0 for .not. allocated' (coindexed vs. not)
+! four times != for allocated (before alloc after dealloc, coindexed and not)
+
+! There are also == 0 and != 0 for (de)allocate checks with -fcoarray=single but those
+! aren't prefixed by '(integer(kind=4) *)'
+
+! { dg-final { scan-tree-dump-times "\\(integer\\(kind=4\\) \\*\\) a.data != 0B" 4 "original" } }
+! { dg-final { scan-tree-dump-times "\\(integer\\(kind=4\\) \\*\\) c.x.data != 0B" 4 "original" } }
+! { dg-final { scan-tree-dump-times "\\(integer\\(kind=4\\) \\*\\) a.data == 0B" 2 "original" } }
+! { dg-final { scan-tree-dump-times "\\(integer\\(kind=4\\) \\*\\) c.x.data == 0B" 2 "original" } }
+
+! Expected: always local access and never a call to _gfortran_caf_get
+! { dg-final { scan-tree-dump-not "caf_get" "original" } }
Index: Fortran/gfortran/regression/coarray/codimension.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/codimension.f90
@@ -0,0 +1,49 @@
+! { dg-do run }
+!
+! Based on coarray_lib_token_4.f90 but checking whether the bounds
+! are correctly handled.
+!
+program test_caf
+ implicit none
+ integer, allocatable :: A(:)[:]
+ integer, save :: B(3)[*]
+ integer :: i
+
+ allocate (A(3)[*])
+ A = [1, 2, 3 ]
+ B = [9, 7, 4 ]
+ call foo (A, A, test=1)
+ call foo (A(2:3), B, test=2)
+ call foo (B, A, test=3)
+contains
+ subroutine foo(x, y, test)
+ integer :: x(:)[*]
+ integer, contiguous :: y(:)[*]
+ integer :: test
+ integer :: i, j
+ call bar (x)
+ call expl (y)
+ i = lcobound(x, dim=1)
+ j = ucobound(x, dim=1)
+ if (i /= 1 .or. j /= num_images()) STOP 1
+ i = lcobound(y, dim=1)
+ j = ucobound(y, dim=1)
+ if (i /= 1 .or. j /= num_images()) STOP 2
+ end subroutine foo
+
+ subroutine bar(y)
+ integer :: y(:)[*]
+ integer :: i, j
+ i = lcobound(y, dim=1)
+ j = ucobound(y, dim=1)
+ if (i /= 1 .or. j /= num_images()) STOP 3
+ end subroutine bar
+
+ subroutine expl(z)
+ integer :: z(*)[*]
+ integer :: i, j
+ i = lcobound(z, dim=1)
+ j = ucobound(z, dim=1)
+ if (i /= 1 .or. j /= num_images()) STOP 4
+ end subroutine expl
+end program test_caf
Index: Fortran/gfortran/regression/coarray/codimension_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/codimension_2.f90
@@ -0,0 +1,14 @@
+! { dg-do link }
+! { dg-additional-sources "codimension_2a.f90 codimension_2b.f90" }
+!
+! To be used with codimension_2a.f90
+! Check that the coarray declared in the module is accessible
+! by doing a link test
+!
+! Contributed by Alessandro Fanfarillo.
+!
+module global_coarrays
+ implicit none
+ integer,parameter :: n=10
+ integer :: b(10)[*]
+end module global_coarrays
Index: Fortran/gfortran/regression/coarray/codimension_2a.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/codimension_2a.f90
@@ -0,0 +1,29 @@
+! { dg-do compile { target { ! *-*-* } } }
+! SKIP THIS FILE
+!
+! Used by codimension_2.f90
+!
+! Check that the coarray declared in the module is accessible
+! by doing a link test
+!
+! Contributed by Alessandro Fanfarillo.
+!
+program testmod
+ use global_coarrays
+ implicit none
+ external ttest
+
+ integer :: me
+
+ me = this_image()
+
+ b = me
+
+ if(me==1) then
+ b(:) = b(:)[2]
+ write(*,*) b
+ elseif (me == 3) then
+ call ttest()
+ end if
+
+end program testmod
Index: Fortran/gfortran/regression/coarray/codimension_2b.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/codimension_2b.f90
@@ -0,0 +1,13 @@
+! { dg-do compile { target { ! *-*-* } } }
+! SKIP THIS FILE
+!
+! Used by codimension_2.f90
+!
+! Additional file to check that using the module doesn't generate
+! a token symbol. (The module is also used by codimension_2.f90.)
+!
+subroutine ttest
+ use global_coarrays
+ implicit none
+ b(:) = b(:)[2]
+end
Index: Fortran/gfortran/regression/coarray/codimension_3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/codimension_3.f90
@@ -0,0 +1,76 @@
+! { dg-do run }
+!
+! PR fortran/84135
+!
+! Co-contributed by G. Steinmetz
+!
+! Ensure that coarray shape remains correct
+! after merging the shape from 'dimension'
+!
+program p
+ integer :: i
+ integer, dimension(3) :: x[2,*]
+ data (x(i:i+2:i+1), i=1,2) /1,2,3/
+ integer, dimension(3) :: y[2,3,-3:4,5,7:*] = [1,2,3]
+ integer :: z, z2[2:4,7:9,-2:2,-7:8,-4:*]
+ codimension :: z[2:4,7:9,-2:2,-7:8,-4:*]
+ integer, codimension[1:*] :: z3[2:4,7:9,-2:2,-7:8,-4:*]
+ dimension :: z(1:2,-3:-2,7:7), z2(1:2,-3:-2,7:7), z3(1:2,-3:-2,7:7)
+ integer, codimension[2:4,7:9,-2:2,-7:8,-4:*], dimension(1:2,-3:-2,7:7) :: z4
+ integer, codimension[*], dimension(1:2,-3:-2,7:7) :: z5[2:4,7:9,-2:2,-7:8,-4:*]
+ integer, codimension[2:4,7:9,-2:2,-7:8,-4:*], dimension(3) :: z6(1:2,-3:-2,7:7)
+ integer, codimension[*], dimension(4) :: z7(1:2,-3:-2,7:7)[2:4,7:9,-2:2,-7:8,-4:*]
+
+ if (any (lcobound(x) /= [1, 1])) stop 1
+ if (any (lcobound(y) /= [1, 1, -3, 1, 7])) stop 3
+ if (any (lcobound(z) /= [2,7,-2,-7,-4])) stop 4
+ if (any (lcobound(z2) /= lcobound(z))) stop 4
+ if (any (lcobound(z3) /= lcobound(z))) stop 5
+ if (any (lcobound(z4) /= lcobound(z))) stop 6
+ if (any (lcobound(z5) /= lcobound(z))) stop 7
+ if (any (lcobound(z6) /= lcobound(z))) stop 8
+ if (any (lcobound(z7) /= lcobound(z))) stop 9
+
+ if (any (lbound(x) /= [1])) stop 11
+ if (any (lbound(y) /= [1])) stop 12
+ if (any (lbound(z) /= [1,-3,7])) stop 13
+ if (any (lbound(z2) /= lbound(z))) stop 14
+ if (any (lbound(z3) /= lbound(z))) stop 15
+ if (any (lbound(z4) /= lbound(z))) stop 16
+ if (any (lbound(z5) /= lbound(z))) stop 17
+ if (any (lbound(z6) /= lbound(z))) stop 18
+ if (any (lbound(z7) /= lbound(z))) stop 19
+
+ if (any (ubound(x) /= [3])) stop 21
+ if (any (ubound(y) /= [3])) stop 22
+ if (any (ubound(z) /= [2,-2,7])) stop 23
+ if (any (ubound(z2) /= ubound(z))) stop 24
+ if (any (ubound(z3) /= ubound(z))) stop 25
+ if (any (ubound(z4) /= ubound(z))) stop 26
+ if (any (ubound(z5) /= ubound(z))) stop 27
+ if (any (ubound(z6) /= ubound(z))) stop 28
+ if (any (ubound(z7) /= ubound(z))) stop 29
+
+ if (any (ucobound(z2) /= ucobound(z))) stop 31
+ if (any (ucobound(z3) /= ucobound(z))) stop 32
+ if (any (ucobound(z4) /= ucobound(z))) stop 33
+ if (any (ucobound(z5) /= ucobound(z))) stop 34
+ if (any (ucobound(z6) /= ucobound(z))) stop 35
+ if (any (ucobound(z7) /= ucobound(z))) stop 36
+
+ if (num_images() == 1) then
+ if (any (ucobound(x) /= [2, lbound(x,dim=1)])) stop 37
+ if (any (ucobound(y) /= [2, 3, 4, 5, 7])) stop 38
+ if (any (ucobound(z) /= [4,9,2,8,-4])) stop 39
+ else
+ if (ucobound(x, dim=1) /= 2) stop 41
+ if (ucobound(y, dim=1) /= 2) stop 42
+ if (ucobound(y, dim=2) /= 3) stop 43
+ if (ucobound(y, dim=3) /= 4) stop 44
+ if (ucobound(y, dim=4) /= 5) stop 45
+ if (ucobound(z, dim=1) /= 4) stop 46
+ if (ucobound(z, dim=2) /= 9) stop 47
+ if (ucobound(z, dim=3) /= 2) stop 48
+ if (ucobound(z, dim=4) /= 8) stop 49
+ endif
+end
Index: Fortran/gfortran/regression/coarray/coindexed_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/coindexed_1.f90
@@ -0,0 +1,1459 @@
+! { dg-do run }
+!
+!
+program test
+ implicit none
+ call char_test()
+contains
+subroutine char_test()
+ character(len=3, kind=1), save :: str1a[*], str1b(5)[*]
+ character(len=7, kind=1), save :: str2a[*], str2b(5)[*]
+ character(len=3, kind=4), save :: ustr1a[*], ustr1b(5)[*]
+ character(len=7, kind=4), save :: ustr2a[*], ustr2b(5)[*]
+
+ ! ---------- Assign to coindexed variable -------------
+
+ ! - - - - - scalar = scalar
+
+ ! SCALAR - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ str2a = 1_"XXXXXXX"
+ if (this_image() == num_images()) then
+ str2a[1] = str1a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2a /= 1_"abc ") STOP 1
+ else
+ if (str2a /= 1_"XXXXXXX") STOP 2
+ end if
+
+ ! SCALAR - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ ustr2a = 4_"XXXXXXX"
+ if (this_image() == num_images()) then
+ ustr2a[1] = ustr1a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2a /= 4_"abc ") STOP 3
+ else
+ if (ustr2a /= 4_"XXXXXXX") STOP 4
+ end if
+
+ ! SCALAR - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcde"
+ str1a = 1_"XXX"
+ if (this_image() == num_images()) then
+ str1a[1] = str2a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1a /= 1_"abc") STOP 5
+ else
+ if (str1a /= 1_"XXX") STOP 6
+ end if
+
+ ! SCALAR - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcde"
+ ustr1a = 4_"XXX"
+ if (this_image() == num_images()) then
+ ustr1a[1] = ustr2a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1a /= 4_"abc") STOP 7
+ else
+ if (ustr1a /= 4_"XXX") STOP 8
+ end if
+
+ ! - - - - - array = array
+
+ ! contiguous ARRAY - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1b(1) = 1_"abc"
+ str1b(2) = 1_"def"
+ str1b(3) = 1_"gjh"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b(:)[1] = str1b
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"def " &
+ .or. str2b(3) /= 1_"gjh ") STOP 9
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 10
+ end if
+
+ ! contiguous ARRAY - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1b(1) = 4_"abc"
+ ustr1b(2) = 4_"def"
+ ustr1b(3) = 4_"gjh"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b(:)[1] = ustr1b
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"def " &
+ .or. ustr2b(3) /= 4_"gjh ") STOP 11
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 12
+ end if
+
+ ! contiguous ARRAY - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2b(1) = 1_"abcdefg"
+ str2b(2) = 1_"hijklmn"
+ str2b(3) = 1_"opqrstu"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b(:)[1] = str2b
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"hij" &
+ .or. str1b(3) /= 1_"opq") STOP 13
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 14
+ end if
+
+ ! contiguous ARRAY - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2b(1) = 4_"abcdefg"
+ ustr2b(2) = 4_"hijklmn"
+ ustr2b(3) = 4_"opqrstu"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b(:)[1] = ustr2b
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"hij" &
+ .or. ustr1b(3) /= 4_"opq") STOP 15
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 16
+ end if
+
+ ! - - - - - array = scalar
+
+ ! contiguous ARRAY - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b(:)[1] = str1a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"abc " &
+ .or. str2b(3) /= 1_"abc ") STOP 17
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 18
+ end if
+
+ ! contiguous ARRAY - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b(:)[1] = ustr1a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"abc " &
+ .or. ustr2b(3) /= 4_"abc ") STOP 19
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 20
+ end if
+
+ ! contiguous ARRAY - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcdefg"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b(:)[1] = str2a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"abc" &
+ .or. str1b(3) /= 1_"abc") STOP 21
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 22
+ end if
+
+ ! contiguous ARRAY - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcdefg"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b(:)[1] = ustr2a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"abc" &
+ .or. ustr1b(3) /= 4_"abc") STOP 23
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 24
+ end if
+
+ ! ---------- Take from a coindexed variable -------------
+
+ ! - - - - - scalar = scalar
+
+ ! SCALAR - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ str2a = 1_"XXXXXXX"
+ if (this_image() == num_images()) then
+ str2a = str1a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str2a /= 1_"abc ") STOP 25
+ else
+ if (str2a /= 1_"XXXXXXX") STOP 26
+ end if
+
+ ! SCALAR - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ ustr2a = 4_"XXXXXXX"
+ if (this_image() == num_images()) then
+ ustr2a = ustr1a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr2a /= 4_"abc ") STOP 27
+ else
+ if (ustr2a /= 4_"XXXXXXX") STOP 28
+ end if
+
+ ! SCALAR - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcde"
+ str1a = 1_"XXX"
+ if (this_image() == num_images()) then
+ str1a = str2a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str1a /= 1_"abc") STOP 29
+ else
+ if (str1a /= 1_"XXX") STOP 30
+ end if
+
+ ! SCALAR - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcde"
+ ustr1a = 4_"XXX"
+ if (this_image() == num_images()) then
+ ustr1a = ustr2a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr1a /= 4_"abc") STOP 31
+ else
+ if (ustr1a /= 4_"XXX") STOP 32
+ end if
+
+ ! - - - - - array = array
+
+ ! contiguous ARRAY - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1b(1) = 1_"abc"
+ str1b(2) = 1_"def"
+ str1b(3) = 1_"gjh"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b = str1b(:)[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"def " &
+ .or. str2b(3) /= 1_"gjh ") STOP 33
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 34
+ end if
+
+ ! contiguous ARRAY - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1b(1) = 4_"abc"
+ ustr1b(2) = 4_"def"
+ ustr1b(3) = 4_"gjh"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b = ustr1b(:)[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"def " &
+ .or. ustr2b(3) /= 4_"gjh ") STOP 35
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 36
+ end if
+
+ ! contiguous ARRAY - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2b(1) = 1_"abcdefg"
+ str2b(2) = 1_"hijklmn"
+ str2b(3) = 1_"opqrstu"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b = str2b(:)[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"hij" &
+ .or. str1b(3) /= 1_"opq") STOP 37
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 38
+ end if
+
+ ! contiguous ARRAY - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2b(1) = 4_"abcdefg"
+ ustr2b(2) = 4_"hijklmn"
+ ustr2b(3) = 4_"opqrstu"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b = ustr2b(:)[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"hij" &
+ .or. ustr1b(3) /= 4_"opq") STOP 39
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 40
+ end if
+
+ ! - - - - - array = scalar
+
+ ! contiguous ARRAY - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b = str1a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"abc " &
+ .or. str2b(3) /= 1_"abc ") STOP 41
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 42
+ end if
+
+ ! contiguous ARRAY - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b = ustr1a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"abc " &
+ .or. ustr2b(3) /= 4_"abc ") STOP 43
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 44
+ end if
+
+ ! contiguous ARRAY - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcdefg"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b = str2a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"abc" &
+ .or. str1b(3) /= 1_"abc") STOP 45
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 46
+ end if
+
+ ! contiguous ARRAY - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcdefg"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b = ustr2a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"abc" &
+ .or. ustr1b(3) /= 4_"abc") STOP 47
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 48
+ end if
+
+
+ ! ---------- coindexed to coindexed variable -------------
+
+ ! - - - - - scalar = scalar
+
+ ! SCALAR - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ str2a = 1_"XXXXXXX"
+ if (this_image() == num_images()) then
+ str2a[1] = str1a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2a /= 1_"abc ") STOP 49
+ else
+ if (str2a /= 1_"XXXXXXX") STOP 50
+ end if
+
+ ! SCALAR - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ ustr2a = 4_"XXXXXXX"
+ if (this_image() == num_images()) then
+ ustr2a[1] = ustr1a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2a /= 4_"abc ") STOP 51
+ else
+ if (ustr2a /= 4_"XXXXXXX") STOP 52
+ end if
+
+ ! SCALAR - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcde"
+ str1a = 1_"XXX"
+ if (this_image() == num_images()) then
+ str1a[1] = str2a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1a /= 1_"abc") STOP 53
+ else
+ if (str1a /= 1_"XXX") STOP 54
+ end if
+
+ ! SCALAR - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcde"
+ ustr1a = 4_"XXX"
+ if (this_image() == num_images()) then
+ ustr1a[1] = ustr2a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1a /= 4_"abc") STOP 55
+ else
+ if (ustr1a /= 4_"XXX") STOP 56
+ end if
+
+ ! - - - - - array = array
+
+ ! contiguous ARRAY - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1b(1) = 1_"abc"
+ str1b(2) = 1_"def"
+ str1b(3) = 1_"gjh"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b(:)[1] = str1b(:)[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"def " &
+ .or. str2b(3) /= 1_"gjh ") STOP 57
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 58
+ end if
+
+ ! contiguous ARRAY - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1b(1) = 4_"abc"
+ ustr1b(2) = 4_"def"
+ ustr1b(3) = 4_"gjh"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b(:)[1] = ustr1b(:)[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"def " &
+ .or. ustr2b(3) /= 4_"gjh ") STOP 59
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 60
+ end if
+
+ ! contiguous ARRAY - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2b(1) = 1_"abcdefg"
+ str2b(2) = 1_"hijklmn"
+ str2b(3) = 1_"opqrstu"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b(:)[1] = str2b(:)[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"hij" &
+ .or. str1b(3) /= 1_"opq") STOP 61
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 62
+ end if
+
+ ! contiguous ARRAY - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2b(1) = 4_"abcdefg"
+ ustr2b(2) = 4_"hijklmn"
+ ustr2b(3) = 4_"opqrstu"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b(:)[1] = ustr2b(:)[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"hij" &
+ .or. ustr1b(3) /= 4_"opq") STOP 63
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 64
+ end if
+
+ ! - - - - - array = scalar
+
+ ! contiguous ARRAY - kind 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b(:)[1] = str1a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"abc " &
+ .or. str2b(3) /= 1_"abc ") STOP 65
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 66
+ end if
+
+ ! contiguous ARRAY - kind 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b(:)[1] = ustr1a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"abc " &
+ .or. ustr2b(3) /= 4_"abc ") STOP 67
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 68
+ end if
+
+ ! contiguous ARRAY - kind 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcdefg"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b(:)[1] = str2a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"abc" &
+ .or. str1b(3) /= 1_"abc") STOP 69
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 70
+ end if
+
+ ! contiguous ARRAY - kind 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcdefg"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b(:)[1] = ustr2a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"abc" &
+ .or. ustr1b(3) /= 4_"abc") STOP 71
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 72
+ end if
+
+ ! ============== char1 <-> char4 =====================
+
+ ! ---------- Assign to coindexed variable -------------
+
+ ! - - - - - scalar = scalar
+
+ ! SCALAR - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ str1a = 1_"XXXXXXX"
+ if (this_image() == num_images()) then
+ str2a[1] = ustr1a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2a /= 1_"abc ") STOP 73
+ else
+ if (str2a /= 1_"XXXXXXX") STOP 74
+ end if
+
+ ! SCALAR - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 4_"abc"
+ ustr2a = 1_"XXXXXXX"
+ if (this_image() == num_images()) then
+ ustr2a[1] = str1a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2a /= 4_"abc ") STOP 75
+ else
+ if (ustr2a /= 4_"XXXXXXX") STOP 76
+ end if
+
+ ! SCALAR - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcde"
+ str1a = 1_"XXX"
+ if (this_image() == num_images()) then
+ str1a[1] = ustr2a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1a /= 1_"abc") STOP 77
+ else
+ if (str1a /= 1_"XXX") STOP 78
+ end if
+
+ ! SCALAR - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 4_"abcde"
+ ustr1a = 1_"XXX"
+ if (this_image() == num_images()) then
+ ustr1a[1] = str2a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1a /= 4_"abc") STOP 79
+ else
+ if (ustr1a /= 4_"XXX") STOP 80
+ end if
+
+ ! - - - - - array = array
+
+ ! contiguous ARRAY - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1b(1) = 4_"abc"
+ ustr1b(2) = 4_"def"
+ ustr1b(3) = 4_"gjh"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b(:)[1] = ustr1b
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"def " &
+ .or. str2b(3) /= 1_"gjh ") STOP 81
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 82
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1b(1) = 1_"abc"
+ str1b(2) = 1_"def"
+ str1b(3) = 1_"gjh"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b(:)[1] = str1b
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"def " &
+ .or. ustr2b(3) /= 4_"gjh ") STOP 83
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 84
+ end if
+
+ ! contiguous ARRAY - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2b(1) = 4_"abcdefg"
+ ustr2b(2) = 4_"hijklmn"
+ ustr2b(3) = 4_"opqrstu"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b(:)[1] = ustr2b
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"hij" &
+ .or. str1b(3) /= 1_"opq") STOP 85
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 86
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2b(1) = 1_"abcdefg"
+ str2b(2) = 1_"hijklmn"
+ str2b(3) = 1_"opqrstu"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b(:)[1] = str2b
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"hij" &
+ .or. ustr1b(3) /= 4_"opq") STOP 87
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 88
+ end if
+
+ ! - - - - - array = scalar
+
+ ! contiguous ARRAY - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b(:)[1] = ustr1a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"abc " &
+ .or. str2b(3) /= 1_"abc ") STOP 89
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 90
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b(:)[1] = str1a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"abc " &
+ .or. ustr2b(3) /= 4_"abc ") STOP 91
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 92
+ end if
+
+ ! contiguous ARRAY - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcdefg"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b(:)[1] = ustr2a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"abc" &
+ .or. str1b(3) /= 1_"abc") STOP 93
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 94
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcdefg"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b(:)[1] = str2a
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"abc" &
+ .or. ustr1b(3) /= 4_"abc") STOP 95
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 96
+ end if
+
+ ! ---------- Take from a coindexed variable -------------
+
+ ! - - - - - scalar = scalar
+
+ ! SCALAR - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ str2a = 1_"XXXXXXX"
+ if (this_image() == num_images()) then
+ str2a = ustr1a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str2a /= 1_"abc ") STOP 97
+ else
+ if (str2a /= 1_"XXXXXXX") STOP 98
+ end if
+
+ ! SCALAR - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ ustr2a = 4_"XXXXXXX"
+ if (this_image() == num_images()) then
+ ustr2a = str1a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr2a /= 4_"abc ") STOP 99
+ else
+ if (ustr2a /= 4_"XXXXXXX") STOP 100
+ end if
+
+ ! SCALAR - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcde"
+ str1a = 1_"XXX"
+ if (this_image() == num_images()) then
+ str1a = ustr2a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str1a /= 1_"abc") STOP 101
+ else
+ if (str1a /= 1_"XXX") STOP 102
+ end if
+
+ ! SCALAR - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcde"
+ ustr1a = 4_"XXX"
+ if (this_image() == num_images()) then
+ ustr1a = str2a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr1a /= 4_"abc") STOP 103
+ else
+ if (ustr1a /= 4_"XXX") STOP 104
+ end if
+
+ ! - - - - - array = array
+
+ ! contiguous ARRAY - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1b(1) = 4_"abc"
+ ustr1b(2) = 4_"def"
+ ustr1b(3) = 4_"gjh"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b = ustr1b(:)[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"def " &
+ .or. str2b(3) /= 1_"gjh ") STOP 105
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 106
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1b(1) = 1_"abc"
+ str1b(2) = 1_"def"
+ str1b(3) = 1_"gjh"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b = str1b(:)[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"def " &
+ .or. ustr2b(3) /= 4_"gjh ") STOP 107
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 108
+ end if
+
+ ! contiguous ARRAY - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2b(1) = 4_"abcdefg"
+ ustr2b(2) = 4_"hijklmn"
+ ustr2b(3) = 4_"opqrstu"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b = ustr2b(:)[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"hij" &
+ .or. str1b(3) /= 1_"opq") STOP 109
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 110
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2b(1) = 1_"abcdefg"
+ str2b(2) = 1_"hijklmn"
+ str2b(3) = 1_"opqrstu"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b = str2b(:)[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"hij" &
+ .or. ustr1b(3) /= 4_"opq") STOP 111
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 112
+ end if
+
+ ! - - - - - array = scalar
+
+ ! contiguous ARRAY - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b = ustr1a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"abc " &
+ .or. str2b(3) /= 1_"abc ") STOP 113
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 114
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b = str1a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"abc " &
+ .or. ustr2b(3) /= 4_"abc ") STOP 115
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 116
+ end if
+
+ ! contiguous ARRAY - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcdefg"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b = ustr2a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"abc" &
+ .or. str1b(3) /= 1_"abc") STOP 117
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 118
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcdefg"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b = str2a[1]
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"abc" &
+ .or. ustr1b(3) /= 4_"abc") STOP 119
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 120
+ end if
+
+
+ ! ---------- coindexed to coindexed variable -------------
+
+ ! - - - - - scalar = scalar
+
+ ! SCALAR - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ str2a = 1_"XXXXXXX"
+ if (this_image() == num_images()) then
+ str2a[1] = ustr1a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2a /= 1_"abc ") STOP 121
+ else
+ if (str2a /= 1_"XXXXXXX") STOP 122
+ end if
+
+ ! SCALAR - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ ustr2a = 4_"XXXXXXX"
+ if (this_image() == num_images()) then
+ ustr2a[1] = str1a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2a /= 4_"abc ") STOP 123
+ else
+ if (ustr2a /= 4_"XXXXXXX") STOP 124
+ end if
+
+ ! SCALAR - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcde"
+ str1a = 1_"XXX"
+ if (this_image() == num_images()) then
+ str1a[1] = ustr2a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1a /= 1_"abc") STOP 125
+ else
+ if (str1a /= 1_"XXX") STOP 126
+ end if
+
+ ! SCALAR - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcde"
+ ustr1a = 4_"XXX"
+ if (this_image() == num_images()) then
+ ustr1a[1] = str2a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1a /= 4_"abc") STOP 127
+ else
+ if (ustr1a /= 4_"XXX") STOP 128
+ end if
+
+ ! - - - - - array = array
+
+ ! contiguous ARRAY - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1b(1) = 4_"abc"
+ ustr1b(2) = 4_"def"
+ ustr1b(3) = 4_"gjh"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b(:)[1] = ustr1b(:)[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"def " &
+ .or. str2b(3) /= 1_"gjh ") STOP 129
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 130
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1b(1) = 1_"abc"
+ str1b(2) = 1_"def"
+ str1b(3) = 1_"gjh"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b(:)[1] = str1b(:)[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"def " &
+ .or. ustr2b(3) /= 4_"gjh ") STOP 131
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 132
+ end if
+
+ ! contiguous ARRAY - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2b(1) = 4_"abcdefg"
+ ustr2b(2) = 4_"hijklmn"
+ ustr2b(3) = 4_"opqrstu"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b(:)[1] = ustr2b(:)[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"hij" &
+ .or. str1b(3) /= 1_"opq") STOP 133
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 134
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2b(1) = 1_"abcdefg"
+ str2b(2) = 1_"hijklmn"
+ str2b(3) = 1_"opqrstu"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b(:)[1] = str2b(:)[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"hij" &
+ .or. ustr1b(3) /= 4_"opq") STOP 135
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 136
+ end if
+
+ ! - - - - - array = scalar
+
+ ! contiguous ARRAY - kind 1 <- 4 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr1a = 4_"abc"
+ str2b(1) = 1_"XXXXXXX"
+ str2b(2) = 1_"YYYYYYY"
+ str2b(3) = 1_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ str2b(:)[1] = ustr1a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str2b(1) /= 1_"abc " .or. str2b(2) /= 1_"abc " &
+ .or. str2b(3) /= 1_"abc ") STOP 137
+ else
+ if (str2b(1) /= 1_"XXXXXXX" .or. str2b(2) /= 1_"YYYYYYY" &
+ .or. str2b(3) /= 1_"ZZZZZZZ") STOP 138
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with padding
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str1a = 1_"abc"
+ ustr2b(1) = 4_"XXXXXXX"
+ ustr2b(2) = 4_"YYYYYYY"
+ ustr2b(3) = 4_"ZZZZZZZ"
+ if (this_image() == num_images()) then
+ ustr2b(:)[1] = str1a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr2b(1) /= 4_"abc " .or. ustr2b(2) /= 4_"abc " &
+ .or. ustr2b(3) /= 4_"abc ") STOP 139
+ else
+ if (ustr2b(1) /= 4_"XXXXXXX" .or. ustr2b(2) /= 4_"YYYYYYY" &
+ .or. ustr2b(3) /= 4_"ZZZZZZZ") STOP 140
+ end if
+
+ ! contiguous ARRAY - kind 1 <- 4 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ ustr2a = 4_"abcdefg"
+ str1b(1) = 1_"XXX"
+ str1b(2) = 1_"YYY"
+ str1b(3) = 1_"ZZZ"
+ if (this_image() == num_images()) then
+ str1b(:)[1] = ustr2a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (str1b(1) /= 1_"abc" .or. str1b(2) /= 1_"abc" &
+ .or. str1b(3) /= 1_"abc") STOP 141
+ else
+ if (str1b(1) /= 1_"XXX" .or. str1b(2) /= 1_"YYY" &
+ .or. str1b(3) /= 1_"ZZZ") STOP 142
+ end if
+
+ ! contiguous ARRAY - kind 4 <- 1 - with trimming
+ str1a = 1_"zzz"; str1b = 1_"zzz"; ustr1a = 4_"zzz"; ustr1b = 4_"zzz"
+ str2a = 1_"zzzzzzzz"; str2b = 1_"zzzzzzzz"
+ ustr2a = 4_"zzzzzzzz"; ustr2b = 4_"zzzzzzzz"
+ str2a = 1_"abcdefg"
+ ustr1b(1) = 4_"XXX"
+ ustr1b(2) = 4_"YYY"
+ ustr1b(3) = 4_"ZZZ"
+ if (this_image() == num_images()) then
+ ustr1b(:)[1] = str2a[mod(1, num_images())+1]
+ end if
+ sync all
+ if (this_image() == 1) then
+ if (ustr1b(1) /= 4_"abc" .or. ustr1b(2) /= 4_"abc" &
+ .or. ustr1b(3) /= 4_"abc") STOP 143
+ else
+ if (ustr1b(1) /= 4_"XXX" .or. ustr1b(2) /= 4_"YYY" &
+ .or. ustr1b(3) /= 4_"ZZZ") STOP 144
+ end if
+
+end subroutine char_test
+end program test
Index: Fortran/gfortran/regression/coarray/collectives_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/collectives_1.f90
@@ -0,0 +1,44 @@
+! { dg-do run }
+!
+! CO_SUM/CO_MIN/CO_MAX
+!
+program test
+ implicit none
+ intrinsic co_max
+ intrinsic co_min
+ intrinsic co_sum
+ call test_min
+ call test_max
+ call test_sum
+contains
+ subroutine test_max
+ integer :: val
+ val = this_image ()
+ call co_max (val, result_image=1)
+ if (this_image() == 1) then
+ !write(*,*) "Maximal value", val
+ if (val /= num_images()) STOP 1
+ end if
+ end subroutine test_max
+
+ subroutine test_min
+ integer :: val
+ val = this_image ()
+ call co_min (val, result_image=1)
+ if (this_image() == 1) then
+ !write(*,*) "Minimal value", val
+ if (val /= 1) STOP 2
+ end if
+ end subroutine test_min
+
+ subroutine test_sum
+ integer :: val, n
+ val = this_image ()
+ call co_sum (val, result_image=1)
+ if (this_image() == 1) then
+ !write(*,*) "The sum is ", val
+ n = num_images()
+ if (val /= (n**2 + n)/2) STOP 3
+ end if
+ end subroutine test_sum
+end program test
Index: Fortran/gfortran/regression/coarray/collectives_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/collectives_2.f90
@@ -0,0 +1,76 @@
+! { dg-do run }
+!
+! CO_SUM/CO_MIN/CO_MAX
+!
+program test
+ implicit none
+ intrinsic co_max
+ intrinsic co_min
+ intrinsic co_sum
+ integer :: val(3), tmp_val(3)
+ integer :: vec(3)
+ vec = [2,3,1]
+ if (this_image() == 1) then
+ val(1) = 42
+ else
+ val(1) = -99
+ endif
+ val(2) = this_image()
+ if (this_image() == num_images()) then
+ val(3) = -55
+ else
+ val(3) = 101
+ endif
+ tmp_val = val
+ call test_min
+ val = tmp_val
+ call test_max
+ val = tmp_val
+ call test_sum
+contains
+ subroutine test_max
+ integer :: tmp
+ call co_max (val(::2))
+ if (num_images() > 1) then
+ if (any (val /= [42, this_image(), 101])) STOP 1
+ else
+ if (any (val /= [42, this_image(), -55])) STOP 2
+ endif
+
+ val = tmp_val
+ call co_max (val(:))
+ if (num_images() > 1) then
+ if (any (val /= [42, num_images(), 101])) STOP 3
+ else
+ if (any (val /= [42, num_images(), -55])) STOP 4
+ endif
+ end subroutine test_max
+
+ subroutine test_min
+ call co_min (val, result_image=num_images())
+ if (this_image() == num_images()) then
+ !write(*,*) "Minimal value", val
+ if (num_images() > 1) then
+ if (any (val /= [-99, 1, -55])) STOP 5
+ else
+ if (any (val /= [42, 1, -55])) STOP 6
+ endif
+ else
+ if (any (val /= tmp_val)) STOP 7
+ endif
+ end subroutine test_min
+
+ subroutine test_sum
+ integer :: n
+ n = 88
+ call co_sum (val, result_image=1, stat=n)
+ if (n /= 0) STOP 8
+ if (this_image() == 1) then
+ n = num_images()
+ !write(*,*) "The sum is ", val
+ if (any (val /= [42 + (n-1)*(-99), (n**2 + n)/2, -55+(n-1)*101])) STOP 9
+ else
+ if (any (val /= tmp_val)) STOP 10
+ end if
+ end subroutine test_sum
+end program test
Index: Fortran/gfortran/regression/coarray/collectives_3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/collectives_3.f90
@@ -0,0 +1,136 @@
+! { dg-do run }
+!
+! CO_BROADCAST
+!
+program test
+ implicit none
+ intrinsic co_broadcast
+
+ type t
+ integer :: i
+ character(len=1) :: c
+ real(8) :: x(3), y(3)
+ end type t
+
+ integer :: i, j(10), stat
+ complex :: a(5,5)
+ character(kind=1, len=5) :: str1, errstr
+ character(kind=4, len=8) :: str2(2)
+ type(t) :: dt(4)
+
+ i = 1
+ j = 55
+ a = 99.0
+ str1 = 1_"XXXXX"
+ str2 = 4_"YYYYYYYY"
+ dt = t(1, 'C', [1.,2.,3.], [3,3,3])
+ errstr = "ZZZZZ"
+
+ if (this_image() == num_images()) then
+ i = 2
+ j = 66
+ a = -99.0
+ str1 = 1_"abcd"
+ str2 = 4_"12 3 4 5"
+ dt = t(-1, 'a', [3.,1.,8.], [99,24,5])
+ end if
+ sync all
+
+ call co_broadcast(i, source_image=num_images(), stat=stat, errmsg=errstr)
+ if (stat /= 0) STOP 1
+ if (errstr /= "ZZZZZ") STOP 2
+ if (i /= 2) STOP 3
+
+ call co_broadcast(j, source_image=num_images(), stat=stat, errmsg=errstr)
+ if (stat /= 0) STOP 4
+ if (errstr /= "ZZZZZ") STOP 5
+ if (any (j /= 66)) STOP 1
+
+ call co_broadcast(a, source_image=num_images(), stat=stat, errmsg=errstr)
+ if (stat /= 0) STOP 6
+ if (errstr /= "ZZZZZ") STOP 7
+ if (any (a /= -99.0)) STOP 2
+
+ call co_broadcast(str1, source_image=num_images(), stat=stat, errmsg=errstr)
+ if (stat /= 0) STOP 8
+ if (errstr /= "ZZZZZ") STOP 9
+ if (str1 /= "abcd") STOP 10
+
+ call co_broadcast(str2, source_image=num_images(), stat=stat, errmsg=errstr)
+ if (stat /= 0) STOP 11
+ if (errstr /= "ZZZZZ") STOP 12
+ if (any (str2 /= 4_"12 3 4 5")) STOP 3
+
+ call co_broadcast(dt, source_image=num_images(), stat=stat, errmsg=errstr)
+ if (stat /= 0) STOP 13
+ if (errstr /= "ZZZZZ") STOP 14
+ if (any (dt(:)%i /= -1)) STOP 15
+ if (any (dt(:)%c /= 'a')) STOP 16
+ if (any (dt(:)%x(1) /= 3.)) STOP 17
+ if (any (dt(:)%x(2) /= 1.)) STOP 18
+ if (any (dt(:)%x(3) /= 8.)) STOP 19
+ if (any (dt(:)%y(1) /= 99.)) STOP 20
+ if (any (dt(:)%y(2) /= 24.)) STOP 21
+ if (any (dt(:)%y(3) /= 5.)) STOP 22
+
+ sync all
+ dt = t(1, 'C', [1.,2.,3.], [3,3,3])
+ sync all
+ if (this_image() == num_images()) then
+ str2 = 4_"001122"
+ dt(2:4) = t(-2, 'i', [9.,2.,3.], [4,44,321])
+ end if
+
+ call co_broadcast(str2(::2), source_image=num_images(), stat=stat, &
+ errmsg=errstr)
+ if (stat /= 0) STOP 23
+ if (errstr /= "ZZZZZ") STOP 24
+ if (str2(1) /= 4_"001122") STOP 25
+ if (this_image() == num_images()) then
+ if (str2(1) /= 4_"001122") STOP 26
+ else
+ if (str2(2) /= 4_"12 3 4 5") STOP 27
+ end if
+
+ call co_broadcast(dt(2::2), source_image=num_images(), stat=stat, &
+ errmsg=errstr)
+ if (stat /= 0) STOP 28
+ if (errstr /= "ZZZZZ") STOP 29
+ if (this_image() == num_images()) then
+ if (any (dt(1:1)%i /= 1)) STOP 30
+ if (any (dt(1:1)%c /= 'C')) STOP 31
+ if (any (dt(1:1)%x(1) /= 1.)) STOP 32
+ if (any (dt(1:1)%x(2) /= 2.)) STOP 33
+ if (any (dt(1:1)%x(3) /= 3.)) STOP 34
+ if (any (dt(1:1)%y(1) /= 3.)) STOP 35
+ if (any (dt(1:1)%y(2) /= 3.)) STOP 36
+ if (any (dt(1:1)%y(3) /= 3.)) STOP 37
+
+ if (any (dt(2:)%i /= -2)) STOP 38
+ if (any (dt(2:)%c /= 'i')) STOP 39
+ if (any (dt(2:)%x(1) /= 9.)) STOP 40
+ if (any (dt(2:)%x(2) /= 2.)) STOP 41
+ if (any (dt(2:)%x(3) /= 3.)) STOP 42
+ if (any (dt(2:)%y(1) /= 4.)) STOP 43
+ if (any (dt(2:)%y(2) /= 44.)) STOP 44
+ if (any (dt(2:)%y(3) /= 321.)) STOP 45
+ else
+ if (any (dt(1::2)%i /= 1)) STOP 46
+ if (any (dt(1::2)%c /= 'C')) STOP 47
+ if (any (dt(1::2)%x(1) /= 1.)) STOP 48
+ if (any (dt(1::2)%x(2) /= 2.)) STOP 49
+ if (any (dt(1::2)%x(3) /= 3.)) STOP 50
+ if (any (dt(1::2)%y(1) /= 3.)) STOP 51
+ if (any (dt(1::2)%y(2) /= 3.)) STOP 52
+ if (any (dt(1::2)%y(3) /= 3.)) STOP 53
+
+ if (any (dt(2::2)%i /= -2)) STOP 54
+ if (any (dt(2::2)%c /= 'i')) STOP 55
+ if (any (dt(2::2)%x(1) /= 9.)) STOP 56
+ if (any (dt(2::2)%x(2) /= 2.)) STOP 57
+ if (any (dt(2::2)%x(3) /= 3.)) STOP 58
+ if (any (dt(2::2)%y(1) /= 4.)) STOP 59
+ if (any (dt(2::2)%y(2) /= 44.)) STOP 60
+ if (any (dt(2::2)%y(3) /= 321.)) STOP 61
+ endif
+end program test
Index: Fortran/gfortran/regression/coarray/collectives_4.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/collectives_4.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+!
+! CO_REDUCE
+!
+implicit none (type, external)
+intrinsic :: co_reduce
+integer :: stat
+integer :: i4, i4_2, i
+
+i4 = 21 * this_image()
+i4_2 = 21
+do i = 2, num_images()
+ i4_2 = i4_2 * 21 * i
+end do
+call co_reduce(i4, op_i4, stat=stat)
+if (stat /= 0) STOP 1
+if (i4_2 /= i4) STOP 2
+
+contains
+ pure integer function op_i4(a,b)
+ integer, value :: a, b
+ op_i4 = a * b
+ end function op_i4
+end
Index: Fortran/gfortran/regression/coarray/cosubscript_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/cosubscript_1.f90
@@ -0,0 +1,66 @@
+! { dg-do run }
+!
+! From the HPCTools Group of University of Houston
+!
+! For a coindexed object, its cosubscript list determines the image
+! index in the same way that a subscript list determines the subscript
+! order value for an array element
+
+! Run at least with 3 images for the normal checking code
+! Modified to also accept a single or two images
+program cosubscript_test
+ implicit none
+
+ integer, parameter :: X = 3, Y = 2
+ integer, parameter :: P = 1, Q = -1
+ integer :: me
+ integer :: i,j,k
+
+ integer :: scalar[0:P, -1:Q, *]
+
+ integer :: dim3_max, counter
+ logical :: is_err
+
+ is_err = .false.
+ me = this_image()
+ scalar = me
+ dim3_max = num_images() / ( (P+1)*(Q+2) )
+
+ sync all
+
+ if (num_images() == 1) then
+ k = 1
+ j = -1
+ i = 0
+ if (scalar[i,j,k] /= this_image()) STOP 1
+ stop "OK"
+ else if (num_images() == 2) then
+ k = 1
+ j = -1
+ counter = 0
+ do i = 0,P
+ counter = counter+1
+ if (counter /= scalar[i,j,k]) STOP 1
+ end do
+ stop "OK"
+ end if
+
+ ! ******* SCALAR ***********
+ counter = 0
+ do k = 1, dim3_max
+ do j = -1,Q
+ do i = 0,P
+ counter = counter+1
+ if (counter /= scalar[i,j,k]) then
+ print * , "Error in cosubscript translation scalar"
+ print * , "[", i,",",j,",",k,"] = ",scalar[i,j,k],"/=",counter
+ is_err = .true.
+ end if
+ end do
+ end do
+ end do
+
+ if (is_err) then
+ STOP 2
+ end if
+end program cosubscript_test
Index: Fortran/gfortran/regression/coarray/data_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/data_1.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+!
+! PR fortran/71068
+!
+! Contributed by Gerhard Steinmetz
+!
+program p
+ integer :: a(2)[*]
+ data a(1)[1] /1/ ! { dg-error "cannot have a coindex" }
+ data a(2)[1] /2/ ! { dg-error "cannot have a coindex" }
+end
Index: Fortran/gfortran/regression/coarray/dummy_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/dummy_1.f90
@@ -0,0 +1,70 @@
+! { dg-do run }
+!
+! PR fortran/18918
+!
+! Check whether assumed-shape's cobounds are properly handled
+!
+ implicit none
+ integer :: B(1)[*]
+ integer :: C(8:11)[-3:10,43:*]
+ integer, allocatable :: D(:)[:,:]
+
+ allocate (D(20)[2:3,5:*])
+
+ call sub (B,5)
+ call sub (C,3)
+ call sub (D,3)
+
+ call sub2 (B, -3)
+ call sub2 (C, 44)
+ call sub2 (D, 44)
+
+ call sub3 (B)
+ call sub3 (C)
+ call sub3 (D)
+
+ call sub4 (B)
+ call sub4 (C)
+ call sub4 (D)
+
+ call sub5 (D)
+ contains
+
+ subroutine sub(A,n)
+ integer :: n
+ integer :: A(n:)[n:2*n,3*n:*]
+ if (lbound(A,dim=1) /= n) STOP 1
+ if (any (lcobound(A) /= [n, 3*n])) STOP 2
+ if (ucobound(A, dim=1) /= 2*n) STOP 3
+ end subroutine sub
+
+ subroutine sub2(A,n)
+ integer :: n
+ integer :: A(:)[-n:*]
+ if (lbound(A,dim=1) /= 1) STOP 4
+ if (lcobound(A, dim=1) /= -n) STOP 5
+ end subroutine sub2
+
+ subroutine sub3(A)
+ integer :: A(:)[0,*]
+ if (lbound(A,dim=1) /= 1) STOP 6
+ if (lcobound(A, dim=1) /= 1) STOP 7
+ if (ucobound(A, dim=1) /= 0) STOP 8
+ if (lcobound(A, dim=2) /= 1) STOP 9
+ end subroutine sub3
+
+ subroutine sub4(A)
+ integer :: A(:)[*]
+ if (lbound(A,dim=1) /= 1) STOP 10
+ if (lcobound(A, dim=1) /= 1) STOP 11
+ end subroutine sub4
+
+ subroutine sub5(A)
+ integer, allocatable :: A(:)[:,:]
+
+ if (lbound(A,dim=1) /= 1) STOP 12
+ if (lcobound(A, dim=1) /= 2) STOP 13
+ if (ucobound(A, dim=1) /= 3) STOP 14
+ if (lcobound(A, dim=2) /= 5) STOP 15
+ end subroutine sub5
+ end
Index: Fortran/gfortran/regression/coarray/dummy_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/dummy_2.f90
@@ -0,0 +1,26 @@
+! { dg-do compile }
+!
+! PR fortran/99817
+!
+! Contributed by G. Steinmetz
+!
+subroutine s1 (x)
+ character(*) :: x(*)[*]
+end
+
+subroutine s2 (x)
+ character(*), dimension(*), codimension[*] :: x
+ integer :: i
+ i = len(x)
+end
+
+subroutine s3 (x, y)
+ character(*), dimension(:) :: x[*]
+ character(*) :: y
+end
+
+subroutine s4 (x, y, z)
+ character(*), dimension(:) :: x[2, *]
+ character(*), dimension(*) :: y
+ character(*) :: z
+end
Index: Fortran/gfortran/regression/coarray/event_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/event_1.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+!
+! Run-time test for EVENT_TYPE
+!
+use iso_fortran_env, only: event_type
+implicit none
+
+type(event_type), save :: var[*]
+integer :: count, stat
+
+count = -42
+call event_query (var, count)
+if (count /= 0) STOP 1
+
+stat = 99
+event post (var, stat=stat)
+if (stat /= 0) STOP 2
+call event_query(var, count, stat=stat)
+if (count /= 1 .or. stat /= 0) STOP 3
+
+stat = 99
+event post (var[this_image()])
+call event_query(var, count)
+if (count /= 2) STOP 4
+
+stat = 99
+event wait (var)
+call event_query(var, count)
+if (count /= 1) STOP 5
+
+stat = 99
+event post (var)
+call event_query(var, count)
+if (count /= 2) STOP 6
+
+stat = 99
+event post (var)
+call event_query(var, count)
+if (count /= 3) STOP 7
+
+stat = 99
+event wait (var, until_count=2)
+call event_query(var, count)
+if (count /= 1) STOP 8
+
+stat = 99
+event wait (var, stat=stat, until_count=1)
+if (stat /= 0) STOP 9
+call event_query(event=var, stat=stat, count=count)
+if (count /= 0 .or. stat /= 0) STOP 10
+end
Index: Fortran/gfortran/regression/coarray/event_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/event_2.f90
@@ -0,0 +1,89 @@
+! { dg-do run }
+!
+! Run-time test for EVENT_TYPE
+!
+use iso_fortran_env, only: event_type
+implicit none
+
+type(event_type), save, allocatable :: var(:)[:]
+integer :: count, stat
+
+allocate(var(3)[*])
+
+count = -42
+call event_query (var(1), count)
+if (count /= 0) STOP 1
+call event_query (var(1), count)
+if (count /= 0) STOP 2
+call event_query (var(2), count)
+if (count /= 0) STOP 3
+call event_query (var(3), count)
+if (count /= 0) STOP 4
+
+stat = 99
+event post (var(2), stat=stat)
+if (stat /= 0) STOP 5
+call event_query (var(1), count)
+if (count /= 0) STOP 6
+call event_query(var(2), count, stat=stat)
+if (count /= 1 .or. stat /= 0) STOP 7
+call event_query (var(3), count)
+if (count /= 0) STOP 8
+
+stat = 99
+event post (var(2)[this_image()])
+call event_query(var(1), count)
+if (count /= 0) STOP 9
+call event_query(var(2), count)
+if (count /= 2) STOP 10
+call event_query(var(2), count)
+if (count /= 2) STOP 11
+call event_query(var(3), count)
+if (count /= 0) STOP 12
+
+stat = 99
+event wait (var(2))
+call event_query(var(1), count)
+if (count /= 0) STOP 13
+call event_query(var(2), count)
+if (count /= 1) STOP 14
+call event_query(var(3), count)
+if (count /= 0) STOP 15
+
+stat = 99
+event post (var(2))
+call event_query(var(1), count)
+if (count /= 0) STOP 16
+call event_query(var(2), count)
+if (count /= 2) STOP 17
+call event_query(var(3), count)
+if (count /= 0) STOP 18
+
+stat = 99
+event post (var(2))
+call event_query(var(1), count)
+if (count /= 0) STOP 19
+call event_query(var(2), count)
+if (count /= 3) STOP 20
+call event_query(var(3), count)
+if (count /= 0) STOP 21
+
+stat = 99
+event wait (var(2), until_count=2)
+call event_query(var(1), count)
+if (count /= 0) STOP 22
+call event_query(var(2), count)
+if (count /= 1) STOP 23
+call event_query(var(3), count)
+if (count /= 0) STOP 24
+
+stat = 99
+event wait (var(2), stat=stat, until_count=1)
+if (stat /= 0) STOP 25
+call event_query(event=var(1), stat=stat, count=count)
+if (count /= 0 .or. stat /= 0) STOP 26
+call event_query(event=var(2), stat=stat, count=count)
+if (count /= 0 .or. stat /= 0) STOP 27
+call event_query(event=var(3), stat=stat, count=count)
+if (count /= 0 .or. stat /= 0) STOP 28
+end
Index: Fortran/gfortran/regression/coarray/event_3.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/event_3.f08
@@ -0,0 +1,20 @@
+! { dg-do run }
+!
+! Check PR fortran/70696 is fixed.
+
+program global_event
+ use iso_fortran_env, only : event_type
+ implicit none
+ type(event_type), save :: x[*]
+
+ call exchange
+ contains
+ subroutine exchange
+ integer :: cnt
+ event post(x[1])
+ event post(x[1])
+ call event_query(x, cnt)
+ if (cnt /= 2) error stop 1
+ event wait(x, until_count=2)
+ end subroutine
+end
Index: Fortran/gfortran/regression/coarray/event_4.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/event_4.f08
@@ -0,0 +1,12 @@
+! { dg-do run }
+!
+! Check that pr 70697 is fixed.
+
+program event_4
+ use iso_fortran_env
+ integer :: nc(1)
+ type(event_type) done[*]
+ nc(1) = 1
+ event post(done[1])
+ event wait(done,until_count=nc(1))
+end
Index: Fortran/gfortran/regression/coarray/fail_image_1.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/fail_image_1.f08
@@ -0,0 +1,10 @@
+! { dg-do compile }
+
+program fail_image_statement_1
+ implicit none
+
+ fail image ! OK
+ fail image (1) ! { dg-error "Syntax error in FAIL IMAGE statement at \\(1\\)" }
+
+end program fail_image_statement_1
+
Index: Fortran/gfortran/regression/coarray/fail_image_2.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/fail_image_2.f08
@@ -0,0 +1,10 @@
+! { dg-do run }
+
+program fail_image_statement_2
+ implicit none
+
+ fail image ! OK
+ error stop "This statement should not be reached."
+
+end program fail_image_statement_2
+
Index: Fortran/gfortran/regression/coarray/failed_images_1.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/failed_images_1.f08
@@ -0,0 +1,20 @@
+! { dg-do compile }
+
+program test_failed_images_1
+ implicit none
+
+ integer, allocatable :: fi(:)
+ real :: r
+ integer :: i
+
+ fi = failed_images() ! OK
+ fi = failed_images(TEAM=1) ! { dg-error "'team' argument of 'failed_images' intrinsic at \\(1\\) not yet supported" }
+ fi = failed_images(KIND=1) ! OK
+ fi = failed_images(KIND=4) ! OK
+ fi = failed_images(KIND=0) ! { dg-error "'kind' argument of 'failed_images' intrinsic at \\\(1\\\) must be positive" }
+ fi = failed_images(KIND=r) ! { dg-error "'kind' argument of 'failed_images' intrinsic at \\\(1\\\) must be INTEGER" }
+ fi = failed_images(KIND=i) ! { dg-error "Constant expression required at \\\(1\\\)" }
+ fi = failed_images(KIND=42) ! { dg-error "'kind' argument of 'failed_images' intrinsic at \\\(1\\\) shall specify a valid integer kind" }
+
+end program test_failed_images_1
+
Index: Fortran/gfortran/regression/coarray/failed_images_2.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/failed_images_2.f08
@@ -0,0 +1,17 @@
+! { dg-do run }
+
+program test_failed_images_2
+ implicit none
+
+ integer, allocatable :: fi(:)
+ integer(kind=1), allocatable :: sfi(:)
+
+ fi = failed_images()
+ if (size(fi) > 0) error stop "failed_images result shall be empty array"
+ sfi = failed_images(KIND=1)
+ if (size(sfi) > 0) error stop "failed_images result shall be empty array"
+ sfi = failed_images(KIND=8)
+ if (size(sfi) > 0) error stop "failed_images result shall be empty array"
+
+end program test_failed_images_2
+
Index: Fortran/gfortran/regression/coarray/get_array.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/get_array.f90
@@ -0,0 +1,288 @@
+! { dg-do run }
+!
+! This program does a correctness check for
+! ... = ARRAY[idx] and ... = SCALAR[idx]
+!
+
+
+!
+! FIXME: two/three has to be modified, test has to be checked and
+! diagnostic has to be removed
+!
+
+program main
+ implicit none
+ integer, parameter :: n = 3
+ integer, parameter :: m = 4
+
+ ! Allocatable coarrays
+ call one(-5, 1)
+ call one(0, 0)
+ call one(1, -5)
+ call one(0, -11)
+
+ ! Static coarrays
+ call two()
+ call three()
+contains
+ subroutine one(lb1, lb2)
+ integer, value :: lb1, lb2
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, allocatable :: caf(:,:)[:]
+ integer, allocatable :: a(:,:), b(:,:), c(:,:)
+
+ allocate(caf(lb1:n+lb1-1, lb2:m+lb2-1)[*], &
+ a(lb1:n+lb1-1, lb2:m+lb2-1), &
+ b(lb1:n+lb1-1, lb2:m+lb2-1), &
+ c(lb1:n+lb1-1, lb2:m+lb2-1))
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(:,:) = b(:,:)
+ c(:,:) = caf(:,:)[num_images()]
+ if (any (a /= c)) then
+ STOP 1
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, lb1, -2
+ a(i,j) = b(i,j)
+ c(i,j) = caf(i,j)[num_images()]
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = lb1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ c(i,j) = caf(i,j)[num_images()]
+ end do
+ end do
+ if (any (a /= c)) then
+ STOP 2
+ end if
+ sync all
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ c(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()]
+ if (any (c /= a)) then
+ STOP 3
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine one
+
+ subroutine two()
+ integer, parameter :: lb1 = -5, lb2 = 1
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, save :: caf(lb1:n+lb1-1, lb2:m+lb2-1)[*]
+ integer, save :: a(lb1:n+lb1-1, lb2:m+lb2-1)
+ integer, save :: b(lb1:n+lb1-1, lb2:m+lb2-1)
+ integer, save :: c(lb1:n+lb1-1, lb2:m+lb2-1)
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(:,:) = b(:,:)
+ c(:,:) = caf(:,:)[num_images()]
+ if (any (a /= c)) then
+ STOP 4
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, lb1, -2
+ a(i,j) = b(i,j)
+ c(i,j) = caf(i,j)[num_images()]
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = lb1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ c(i,j) = caf(i,j)[num_images()]
+ end do
+ end do
+ if (any (a /= c)) then
+ STOP 5
+ end if
+ sync all
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ c(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()]
+ if (any (c /= a)) then
+ STOP 6
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine two
+
+ subroutine three()
+ integer, parameter :: lb1 = 0, lb2 = 0
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, save :: caf(lb1:n+lb1-1, lb2:m+lb2-1)[*]
+ integer, save :: a(lb1:n+lb1-1, lb2:m+lb2-1)
+ integer, save :: b(lb1:n+lb1-1, lb2:m+lb2-1)
+ integer, save :: c(lb1:n+lb1-1, lb2:m+lb2-1)
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(:,:) = b(:,:)
+ c(:,:) = caf(:,:)[num_images()]
+ if (any (a /= c)) then
+ STOP 7
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, lb1, -2
+ a(i,j) = b(i,j)
+ c(i,j) = caf(i,j)[num_images()]
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = lb1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ c(i,j) = caf(i,j)[num_images()]
+ end do
+ end do
+ if (any (a /= c)) then
+ STOP 8
+ end if
+ sync all
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ c = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ c(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()]
+ if (any (c /= a)) then
+ STOP 9
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine three
+end program main
Index: Fortran/gfortran/regression/coarray/get_to_indexed_array_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/get_to_indexed_array_1.f90
@@ -0,0 +1,32 @@
+! { dg-do run }
+
+! Test that index vector on lhs of caf-expression works correctly.
+
+program pr81773
+
+ integer, parameter :: ndim = 5
+ integer :: i
+ integer :: vec(ndim) = -1
+ integer :: res(ndim)[*] = [ (i, i=1, ndim) ]
+ type T
+ integer :: padding
+ integer :: dest(ndim)
+ integer :: src(ndim)
+ end type
+
+ type(T) :: dest
+ type(T), allocatable :: caf[:]
+
+ vec([ndim, 3, 1]) = res(1:3)[1]
+ if (any (vec /= [ 3, -1, 2, -1, 1])) stop 1
+
+ dest = T(42, [ ( -1, i = 1, ndim ) ], [ ( i - 2, i = ndim, 1, -1) ] )
+ dest%dest([ 4,3,2 ]) = res(3:5)[1]
+ if (any (dest%dest /= [-1, 5, 4, 3, -1])) stop 2
+
+ vec(:) = -1
+ allocate(caf[*], source = T(42, [ ( -1, i = 1, ndim ) ], [ ( i - 2, i = ndim, 1, -1) ] ))
+ vec([ 5,3,2 ]) = caf[1]%src(2:4)
+ if (any (vec /= [ -1, 0, 1, -1, 2])) stop 3
+end
+
Index: Fortran/gfortran/regression/coarray/get_to_indirect_array.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/get_to_indirect_array.f90
@@ -0,0 +1,28 @@
+! { dg-do run }
+!
+! Test that pr81773/fortran is fixed.
+
+program get_to_indexed_array
+
+ integer, parameter :: ndim = 5
+ integer :: i
+ integer :: vec(1:ndim) = 0
+ integer :: indx(1:2) = [3, 2]
+ integer :: mat(1:ndim, 1:ndim) = 0
+ integer :: res(1:ndim)[*]=[ (i, i=1, ndim) ]
+
+ ! No sync needed, because this test always is running on single image
+ vec([ndim , 1]) = res(1:2)[1]
+ if (vec(1) /= res(2) .or. vec(ndim) /= res(1)) then
+ print *,"vec: ", vec, " on image: ", this_image()
+ stop 1
+ end if
+
+ mat(2:3,[indx(:)]) = reshape(res(1:4)[1], [2, 2])
+ if (any(mat(2:3, 3:2:-1) /= reshape(res(1:4), [2,2]))) then
+ print *, "mat: ", mat, " on image: ", this_image()
+ stop 2
+ end if
+end
+
+! vim:ts=2:sts=2:sw=2:
Index: Fortran/gfortran/regression/coarray/image_index_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/image_index_1.f90
@@ -0,0 +1,99 @@
+! { dg-do run }
+!
+! Run-time test for IMAGE_INDEX with cobounds only known at
+! the compile time, suitable for any number of NUM_IMAGES()
+! For compile-time cobounds, the -fcoarray=lib version still
+! needs to run-time evalulation if image_index returns > 1
+! as image_index is 0 if the index would exceed num_images().
+!
+! Please set num_images() to >= 13, if possible.
+!
+! PR fortran/18918
+!
+
+program test_image_index
+implicit none
+integer :: index1, index2, index3
+logical :: one
+
+integer, allocatable :: a(:)[:,:,:], b(:)[:,:], c(:,:)[:]
+integer, save :: d(2)[-1:3, *]
+integer, save :: e(2)[-1:-1, 3:*]
+
+one = num_images() == 1
+
+allocate(a(1)[3:3, -4:-3, 88:*])
+allocate(b(2)[-1:0,0:*])
+allocate(c(3,3)[*])
+
+index1 = image_index(a, [3, -4, 88] )
+index2 = image_index(b, [-1, 0] )
+index3 = image_index(c, [1] )
+if (index1 /= 1 .or. index2 /= 1 .or. index3 /= 1) STOP 1
+
+
+index1 = image_index(a, [3, -3, 88] )
+index2 = image_index(b, [0, 0] )
+index3 = image_index(c, [2] )
+
+if (one .and. (index1 /= 0 .or. index2 /= 0 .or. index3 /= 0)) &
+ STOP 2
+if (.not. one .and. (index1 /= 2 .or. index2 /= 2 .or. index3 /= 2)) &
+ STOP 3
+
+
+index1 = image_index(d, [-1, 1] )
+index2 = image_index(d, [0, 1] )
+
+if (one .and. (index1 /= 1 .or. index2 /= 0)) &
+ STOP 4
+if (.not. one .and. (index1 /= 1 .or. index2 /= 2)) &
+ STOP 5
+
+index1 = image_index(e, [-1, 3] )
+index2 = image_index(e, [-1, 4] )
+
+if (one .and. (index1 /= 1 .or. index2 /= 0)) &
+ STOP 6
+if (.not. one .and. (index1 /= 1 .or. index2 /= 2)) &
+ STOP 7
+
+call test(1, a,b,c)
+
+! The following test is in honour of the F2008 standard:
+deallocate(a)
+allocate(a (10) [10, 0:9, 0:*])
+
+index1 = image_index(a, [1, 0, 0] )
+index2 = image_index(a, [3, 1, 2] ) ! = 213, yeah!
+index3 = image_index(a, [3, 1, 0] ) ! = 13
+
+if (num_images() < 13 .and. (index1 /= 1 .or. index2 /= 0 .or. index3 /= 0)) &
+ STOP 8
+if (num_images() >= 213 .and. (index1 /= 1 .or. index2 /= 213 .or. index3 /= 13)) &
+ STOP 9
+if (num_images() >= 13 .and. (index1 /= 1 .or. index2 /= 0 .or. index3 /= 13)) &
+ STOP 10
+
+
+contains
+subroutine test(n, a, b, c)
+ integer :: n
+ integer :: a(1)[3*n:3*n, -4*n:-3*n, 88*n:*], b(2)[-1*n:0*n,0*n:*], c(3*n,3*n)[*]
+
+ index1 = image_index(a, [3, -4, 88] )
+ index2 = image_index(b, [-1, 0] )
+ index3 = image_index(c, [1] )
+ if (index1 /= 1 .or. index2 /= 1 .or. index3 /= 1) STOP 11
+
+
+ index1 = image_index(a, [3, -3, 88] )
+ index2 = image_index(b, [0, 0] )
+ index3 = image_index(c, [2] )
+
+ if (one .and. (index1 /= 0 .or. index2 /= 0 .or. index3 /= 0)) &
+ STOP 12
+ if (.not. one .and. (index1 /= 2 .or. index2 /= 2 .or. index3 /= 2)) &
+ STOP 13
+end subroutine test
+end program test_image_index
Index: Fortran/gfortran/regression/coarray/image_index_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/image_index_2.f90
@@ -0,0 +1,76 @@
+! { dg-do run }
+!
+! Scalar coarray
+!
+! Run-time test for IMAGE_INDEX with cobounds only known at
+! the compile time, suitable for any number of NUM_IMAGES()
+! For compile-time cobounds, the -fcoarray=lib version still
+! needs to run-time evalulation if image_index returns > 1
+! as image_index is 0 if the index would exceed num_images().
+!
+! Please set num_images() to >= 13, if possible.
+!
+! PR fortran/18918
+!
+
+program test_image_index
+implicit none
+integer :: index1, index2, index3
+logical :: one
+
+integer, save :: d[-1:3, *]
+integer, save :: e[-1:-1, 3:*]
+
+one = num_images() == 1
+
+index1 = image_index(d, [-1, 1] )
+index2 = image_index(d, [0, 1] )
+
+if (one .and. (index1 /= 1 .or. index2 /= 0)) &
+ STOP 1
+if (.not. one .and. (index1 /= 1 .or. index2 /= 2)) &
+ STOP 2
+
+index1 = image_index(e, [-1, 3] )
+index2 = image_index(e, [-1, 4] )
+
+if (one .and. (index1 /= 1 .or. index2 /= 0)) &
+ STOP 3
+if (.not. one .and. (index1 /= 1 .or. index2 /= 2)) &
+ STOP 4
+
+call test(1, e, d, e)
+call test(2, e, d, e)
+
+contains
+subroutine test(n, a, b, c)
+ integer :: n
+ integer :: a[3*n:3*n, -4*n:-3*n, 88*n:*], b[-1*n:0*n,0*n:*], c[*]
+
+ index1 = image_index(a, [3*n, -4*n, 88*n] )
+ index2 = image_index(b, [-1, 0] )
+ index3 = image_index(c, [1] )
+
+ if (n == 1) then
+ if (index1 /= 1 .or. index2 /= 1 .or. index3 /= 1) STOP 5
+ else if (num_images() == 1) then
+ if (index1 /= 1 .or. index2 /= 0 .or. index3 /= 1) STOP 6
+ else
+ if (index1 /= 1 .or. index2 /= 2 .or. index3 /= 1) STOP 7
+ end if
+
+ index1 = image_index(a, [3*n, -3*n, 88*n] )
+ index2 = image_index(b, [0, 0] )
+ index3 = image_index(c, [2] )
+
+ if (one .and. (index1 /= 0 .or. index2 /= 0 .or. index3 /= 0)) &
+ STOP 8
+ if (n == 1 .and. num_images() == 2) then
+ if (index1 /= 2 .or. index2 /= 2 .or. index3 /= 2) &
+ STOP 9
+ else if (n == 2 .and. num_images() == 2) then
+ if (index1 /= 0 .or. index2 /= 0 .or. index3 /= 2) &
+ STOP 10
+ end if
+end subroutine test
+end program test_image_index
Index: Fortran/gfortran/regression/coarray/image_index_3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/image_index_3.f90
@@ -0,0 +1,103 @@
+! { dg-do run }
+! { dg-options "-fdefault-integer-8" }
+!
+! As image_index_1.f90 but with -fdefault-integer-8
+! PR fortran/51682
+!
+! Run-time test for IMAGE_INDEX with cobounds only known at
+! the compile time, suitable for any number of NUM_IMAGES()
+! For compile-time cobounds, the -fcoarray=lib version still
+! needs to run-time evalulation if image_index returns > 1
+! as image_index is 0 if the index would exceed num_images().
+!
+! Please set num_images() to >= 13, if possible.
+!
+! PR fortran/18918
+!
+
+program test_image_index
+implicit none
+integer :: index1, index2, index3
+logical :: one
+
+integer, allocatable :: a(:)[:,:,:], b(:)[:,:], c(:,:)[:]
+integer, save :: d(2)[-1:3, *]
+integer, save :: e(2)[-1:-1, 3:*]
+
+one = num_images() == 1
+
+allocate(a(1)[3:3, -4:-3, 88:*])
+allocate(b(2)[-1:0,0:*])
+allocate(c(3,3)[*])
+
+index1 = image_index(a, [3, -4, 88] )
+index2 = image_index(b, [-1, 0] )
+index3 = image_index(c, [1] )
+if (index1 /= 1 .or. index2 /= 1 .or. index3 /= 1) STOP 1
+
+
+index1 = image_index(a, [3, -3, 88] )
+index2 = image_index(b, [0, 0] )
+index3 = image_index(c, [2] )
+
+if (one .and. (index1 /= 0 .or. index2 /= 0 .or. index3 /= 0)) &
+ STOP 2
+if (.not. one .and. (index1 /= 2 .or. index2 /= 2 .or. index3 /= 2)) &
+ STOP 3
+
+
+index1 = image_index(d, [-1, 1] )
+index2 = image_index(d, [0, 1] )
+
+if (one .and. (index1 /= 1 .or. index2 /= 0)) &
+ STOP 4
+if (.not. one .and. (index1 /= 1 .or. index2 /= 2)) &
+ STOP 5
+
+index1 = image_index(e, [-1, 3] )
+index2 = image_index(e, [-1, 4] )
+
+if (one .and. (index1 /= 1 .or. index2 /= 0)) &
+ STOP 6
+if (.not. one .and. (index1 /= 1 .or. index2 /= 2)) &
+ STOP 7
+
+call test(1, a,b,c)
+
+! The following test is in honour of the F2008 standard:
+deallocate(a)
+allocate(a (10) [10, 0:9, 0:*])
+
+index1 = image_index(a, [1, 0, 0] )
+index2 = image_index(a, [3, 1, 2] ) ! = 213, yeah!
+index3 = image_index(a, [3, 1, 0] ) ! = 13
+
+if (num_images() < 13 .and. (index1 /= 1 .or. index2 /= 0 .or. index3 /= 0)) &
+ STOP 8
+if (num_images() >= 213 .and. (index1 /= 1 .or. index2 /= 213 .or. index3 /= 13)) &
+ STOP 9
+if (num_images() >= 13 .and. (index1 /= 1 .or. index2 /= 0 .or. index3 /= 13)) &
+ STOP 10
+
+
+contains
+subroutine test(n, a, b, c)
+ integer :: n
+ integer :: a(1)[3*n:3*n, -4*n:-3*n, 88*n:*], b(2)[-1*n:0*n,0*n:*], c(3*n,3*n)[*]
+
+ index1 = image_index(a, [3, -4, 88] )
+ index2 = image_index(b, [-1, 0] )
+ index3 = image_index(c, [1] )
+ if (index1 /= 1 .or. index2 /= 1 .or. index3 /= 1) STOP 11
+
+
+ index1 = image_index(a, [3, -3, 88] )
+ index2 = image_index(b, [0, 0] )
+ index3 = image_index(c, [2] )
+
+ if (one .and. (index1 /= 0 .or. index2 /= 0 .or. index3 /= 0)) &
+ STOP 12
+ if (.not. one .and. (index1 /= 2 .or. index2 /= 2 .or. index3 /= 2)) &
+ STOP 13
+end subroutine test
+end program test_image_index
Index: Fortran/gfortran/regression/coarray/image_status_1.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/image_status_1.f08
@@ -0,0 +1,26 @@
+! { dg-do compile }
+
+program test_image_status_1
+ implicit none
+
+ integer :: isv
+ integer(kind=1) :: k1
+ integer(kind=2) :: k2
+ integer(kind=4) :: k4
+ integer(kind=8) :: k8
+
+ isv = image_status(1) ! Ok
+ isv = image_status(-1) ! { dg-error "'image' argument of 'image_status' intrinsic at \\(1\\) must be positive" }
+ isv = image_status(0) ! { dg-error "'image' argument of 'image_status' intrinsic at \\(1\\) must be positive" }
+ isv = image_status(.true.) ! { dg-error "'image' argument of 'image_status' intrinsic at \\(1\\) must be INTEGER" }
+ isv = image_status([1,2,3]) ! { dg-error "'image' argument of 'image_status' intrinsic at \\(1\\) must be a scalar" }
+ isv = image_status(k1) ! Ok
+ isv = image_status(k2) ! Ok
+ isv = image_status(k4) ! Ok
+ isv = image_status(k8) ! Ok
+ isv = image_status(1, team=1) ! { dg-error "'team' argument of 'image_status' intrinsic at \\(1\\) not yet supported" }
+ isv = image_status() ! { dg-error "Missing actual argument 'image' in call to 'image_status' at \\(1\\)" }
+ isv = image_status(team=1) ! { dg-error "Missing actual argument 'image' in call to 'image_status' at \\(1\\)" }
+
+end program test_image_status_1
+
Index: Fortran/gfortran/regression/coarray/image_status_2.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/image_status_2.f08
@@ -0,0 +1,12 @@
+! { dg-do run }
+
+program test_image_status_2
+ use iso_fortran_env , only : STAT_STOPPED_IMAGE
+ implicit none
+
+ if (image_status(1) /= 0) error stop "Image 1 should report OK."
+ if (image_status(2) /= STAT_STOPPED_IMAGE) error stop "Image 2 should be stopped."
+ if (image_status(3) /= STAT_STOPPED_IMAGE) error stop "Image 3 should be stopped."
+
+end program test_image_status_2
+
Index: Fortran/gfortran/regression/coarray/lib_realloc_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/lib_realloc_1.f90
@@ -0,0 +1,29 @@
+! { dg-do run }
+!
+! Test that for CAF components _gfortran_caf_deregister is called
+! Test that norealloc happens for CAF components during assignment
+!
+module m
+type t
+ integer, allocatable :: CAF[:]
+end type t
+end module m
+
+program main
+use m
+type(t), target :: x,y
+integer, pointer :: ptr
+allocate(x%caf[*], y%caf[*])
+ptr => y%caf
+ptr = 6
+if (.not.allocated(x%caf)) STOP 1
+if (.not.allocated(y%caf)) STOP 2
+if (y%caf /= 6) STOP 3
+x = y
+if (x%caf /= 6) STOP 4
+if (.not. associated (ptr,y%caf)) STOP 5
+if (associated (ptr,x%caf)) STOP 6
+ptr = 123
+if (y%caf /= 123) STOP 7
+if (x%caf /= 6) STOP 8
+end program main
Index: Fortran/gfortran/regression/coarray/lock_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/lock_1.f90
@@ -0,0 +1,32 @@
+! { dg-do run }
+!
+! LOCK/UNLOCK check
+!
+! PR fortran/18918
+!
+
+use iso_fortran_env
+implicit none
+
+type(lock_type) :: lock[*]
+integer :: stat
+logical :: acquired
+
+LOCK(lock)
+UNLOCK(lock)
+
+stat = 99
+LOCK(lock, stat=stat)
+if (stat /= 0) STOP 1
+stat = 99
+UNLOCK(lock, stat=stat)
+if (stat /= 0) STOP 2
+
+if (this_image() == 1) then
+ acquired = .false.
+ LOCK (lock[this_image()], acquired_lock=acquired)
+ if (.not. acquired) STOP 3
+ UNLOCK (lock[1])
+end if
+end
+
Index: Fortran/gfortran/regression/coarray/lock_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/lock_2.f90
@@ -0,0 +1,89 @@
+! { dg-do run }
+!
+! LOCK/UNLOCK check
+!
+! PR fortran/18918
+!
+
+use iso_fortran_env
+implicit none
+
+type(lock_type), allocatable :: lock1[:]
+type(lock_type), allocatable :: lock2(:,:)[:]
+type(lock_type) :: lock3(4)[*]
+integer :: stat
+logical :: acquired
+
+allocate(lock1[*])
+allocate(lock2(2,2)[*])
+
+LOCK(lock1)
+UNLOCK(lock1)
+
+LOCK(lock2(1,1))
+LOCK(lock2(2,2))
+UNLOCK(lock2(1,1))
+UNLOCK(lock2(2,2))
+
+LOCK(lock3(3))
+LOCK(lock3(4))
+UNLOCK(lock3(3))
+UNLOCK(lock3(4))
+
+stat = 99
+LOCK(lock1, stat=stat)
+if (stat /= 0) STOP 1
+
+LOCK(lock2(1,1), stat=stat)
+if (stat /= 0) STOP 2
+LOCK(lock2(2,2), stat=stat)
+if (stat /= 0) STOP 3
+
+LOCK(lock3(3), stat=stat)
+if (stat /= 0) STOP 4
+LOCK(lock3(4), stat=stat)
+if (stat /= 0) STOP 5
+
+stat = 99
+UNLOCK(lock1, stat=stat)
+if (stat /= 0) STOP 6
+
+UNLOCK(lock2(1,1), stat=stat)
+if (stat /= 0) STOP 7
+UNLOCK(lock2(2,2), stat=stat)
+if (stat /= 0) STOP 8
+
+UNLOCK(lock3(3), stat=stat)
+if (stat /= 0) STOP 9
+UNLOCK(lock3(4), stat=stat)
+if (stat /= 0) STOP 10
+
+if (this_image() == 1) then
+ acquired = .false.
+ LOCK (lock1[this_image()], acquired_lock=acquired)
+ if (.not. acquired) STOP 11
+
+ acquired = .false.
+ LOCK (lock2(1,1)[this_image()], acquired_lock=acquired)
+ if (.not. acquired) STOP 12
+
+ acquired = .false.
+ LOCK (lock2(2,2)[this_image()], acquired_lock=acquired)
+ if (.not. acquired) STOP 13
+
+ acquired = .false.
+ LOCK (lock3(3)[this_image()], acquired_lock=acquired)
+ if (.not. acquired) STOP 14
+
+ acquired = .false.
+ LOCK (lock3(4)[this_image()], acquired_lock=acquired)
+ if (.not. acquired) STOP 15
+
+ UNLOCK (lock1[1])
+ UNLOCK (lock2(1,1)[1])
+ UNLOCK (lock2(2,2)[1])
+ UNLOCK (lock3(3)[1])
+ UNLOCK (lock3(4)[1])
+end if
+end
+
Index: Fortran/gfortran/regression/coarray/move_alloc_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/move_alloc_1.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+!
+! PR fortran/53526
+!
+! Check handling of move_alloc with coarrays
+!
+implicit none
+integer, allocatable :: u[:], v[:], w(:)[:,:], x(:)[:,:]
+
+allocate (u[4:*])
+call move_alloc (u, v)
+if (allocated (u)) STOP 1
+if (lcobound (v, dim=1) /= 4) STOP 2
+if (ucobound (v, dim=1) /= 3 + num_images()) STOP 3
+
+allocate (w(-2:3)[4:5,-1:*])
+call move_alloc (w, x)
+if (allocated (w)) STOP 4
+if (lbound (x, dim=1) /= -2) STOP 5
+if (ubound (x, dim=1) /= 3) STOP 6
+if (any (lcobound (x) /= [4, -1])) STOP 7
+if (any (ucobound (x) /= [5, -2 + (num_images()+1)/2])) STOP 8
+
+end
Index: Fortran/gfortran/regression/coarray/poly_run_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/poly_run_1.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+!
+! Test for polymorphic coarrays
+!
+type t
+end type t
+class(t), allocatable :: A(:)[:,:]
+allocate (A(2)[1:4,-5:*])
+if (any (lcobound(A) /= [1, -5])) STOP 1
+if (num_images() == 1) then
+ if (any (ucobound(A) /= [4, -5])) STOP 2
+else
+ if (ucobound(A,dim=1) /= 4) STOP 3
+end if
+if (allocated(A)) i = 5
+call s(A)
+!call st(A) ! FIXME
+
+contains
+
+subroutine s(x)
+ class(t),allocatable :: x(:)[:,:]
+ if (any (lcobound(x) /= [1, -5])) STOP 4
+ if (num_images() == 1) then
+ if (any (ucobound(x) /= [4, -5])) STOP 5
+ else
+ if (ucobound(x,dim=1) /= 4) STOP 6
+ end if
+end subroutine s
+
+subroutine st(x)
+ class(t) :: x(:)[4,2:*]
+! FIXME
+! if (any (lcobound(x) /= [1, 2])) STOP 7
+! if (lcobound(x, dim=1) /= 1) STOP 8
+! if (lcobound(x, dim=2) /= 2) STOP 9
+! if (this_image() == 1) then
+! if (any (this_image(x) /= lcobound(x))) STOP 10
+! if (this_image(x, dim=1) /= lcobound(x, dim=1)) STOP 11
+! if (this_image(x, dim=2) /= lcobound(x, dim=2)) STOP 12
+! end if
+! if (num_images() == 1) then
+! if (any (ucobound(x) /= [4, 2])) STOP 13
+! if (ucobound(x, dim=1) /= 4) STOP 14
+! if (ucobound(x, dim=2) /= 2) STOP 15
+! else
+! if (ucobound(x,dim=1) /= 4) STOP 16
+! end if
+end subroutine st
+end
+
Index: Fortran/gfortran/regression/coarray/poly_run_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/poly_run_2.f90
@@ -0,0 +1,39 @@
+! { dg-do run }
+!
+! Test for polymorphic coarrays
+!
+type t
+end type t
+class(t), allocatable :: A[:,:]
+allocate (A[1:4,-5:*])
+if (allocated(A)) stop
+if (any (lcobound(A) /= [1, -5])) STOP 1
+if (num_images() == 1) then
+ if (any (ucobound(A) /= [4, -5])) STOP 2
+else
+ if (ucobound(A,dim=1) /= 4) STOP 3
+end if
+if (allocated(A)) i = 5
+call s(A)
+call st(A)
+contains
+subroutine s(x)
+ class(t) :: x[4,2:*]
+ if (any (lcobound(x) /= [1, 2])) STOP 4
+ if (num_images() == 1) then
+ if (any (ucobound(x) /= [4, 2])) STOP 5
+ else
+ if (ucobound(x,dim=1) /= 4) STOP 6
+ end if
+end subroutine s
+subroutine st(x)
+ class(t) :: x[:,:]
+ if (any (lcobound(x) /= [1, -5])) STOP 7
+ if (num_images() == 1) then
+ if (any (ucobound(x) /= [4, -5])) STOP 8
+ else
+ if (ucobound(x,dim=1) /= 4) STOP 9
+ end if
+end subroutine st
+end
+
Index: Fortran/gfortran/regression/coarray/poly_run_3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/poly_run_3.f90
@@ -0,0 +1,39 @@
+! { dg-do run }
+!
+! Check that the bounds of polymorphic coarrays is
+! properly handled.
+!
+type t
+end type t
+class(t), allocatable :: a(:)[:]
+class(t), allocatable :: b[:], d[:]
+
+allocate(a(1)[*])
+if (this_image() == 1 .and. any (this_image(a) /= lcobound(a))) &
+ STOP 1
+if (any (lcobound(a) /= 1)) STOP 2
+if (any (ucobound(a) /= this_image())) STOP 3
+deallocate(a)
+
+allocate(b[*])
+if (this_image() == 1 .and. any (this_image(b) /= lcobound(b))) &
+ STOP 4
+if (any (lcobound(b) /= 1)) STOP 5
+if (any (ucobound(b) /= this_image())) STOP 6
+deallocate(b)
+
+allocate(a(1)[-10:*])
+if (this_image() == 1 .and. any (this_image(a) /= lcobound(a))) &
+ STOP 7
+if (any (lcobound(a) /= -10)) STOP 8
+if (any (ucobound(a) /= -11+this_image())) STOP 9
+deallocate(a)
+
+allocate(d[23:*])
+if (this_image() == 1 .and. any (this_image(d) /= lcobound(d))) &
+ STOP 10
+if (any (lcobound(d) /= 23)) STOP 11
+if (any (ucobound(d) /= 22+this_image())) STOP 12
+deallocate(d)
+
+end
Index: Fortran/gfortran/regression/coarray/pr107441-caf.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/pr107441-caf.f90
@@ -0,0 +1,27 @@
+! { dg-do run }
+!
+! PR fortran/107441
+! Check that with -fcoarray=lib, coarray metadata arguments are passed
+! in the right order to procedures.
+!
+! Contributed by M.Morin
+
+program p
+ integer :: ci[*]
+ ci = 17
+ call s(1, ci, "abcd")
+contains
+ subroutine s(ra, ca, c)
+ integer :: ra, ca[*]
+ character(*) :: c
+ ca[1] = 13
+ if (ra /= 1) stop 1
+ if (this_image() == 1) then
+ if (ca /= 13) stop 2
+ else
+ if (ca /= 17) stop 3
+ end if
+ if (len(c) /= 4) stop 4
+ if (c /= "abcd") stop 5
+ end subroutine s
+end program p
Index: Fortran/gfortran/regression/coarray/pr93671.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/pr93671.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+
+! PR/fortran 93671 - ICE on intrinsic assignment to allocatable derived-type
+! component of coarray
+
+ type flux_planes
+ integer, allocatable :: normals
+ end type
+
+ type package
+ type(flux_planes) surface_fluxes(1)
+ end type
+
+ type(package) mail[*], halo_data
+
+ halo_data%surface_fluxes(1)%normals = 1
+ mail = halo_data
+
+ if (any(size(mail%surface_fluxes) /= [1]) .OR. &
+ mail%surface_fluxes(1)%normals /= 1) then
+ stop 1
+ end if
+end
+
Index: Fortran/gfortran/regression/coarray/ptr_comp_1.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/ptr_comp_1.f08
@@ -0,0 +1,36 @@
+! { dg-do run }
+
+program alloc_comp
+ type t
+ integer, pointer :: z
+ end type
+ type(t), save :: obj[*]
+ integer, allocatable, target :: i[:]
+
+ if (associated(obj%z)) error stop "'z' should not be associated yet."
+ allocate (obj%z)
+ call f(obj)
+ if (associated(obj%z)) error stop "'z' should not be associated anymore."
+
+ allocate(i[*], SOURCE=42)
+ obj%z => i
+ if (.not. allocated(i)) error stop "'i' no longer allocated."
+ i = 15
+ if (obj%z /= 15) error stop "'obj%z' is deep copy and not pointer."
+
+ nullify (obj%z)
+ if (.not. allocated(i)) error stop "'i' should still be allocated."
+ if (associated(obj%z)) error stop "'obj%z' should not be associated anymore."
+
+ obj%z => i
+ call f(obj)
+ ! One can not say anything about i here. The memory should be deallocated, but
+ ! the pointer in i is still set.
+ if (associated(obj%z)) error stop "'obj%z' should not be associated anymore."
+contains
+ subroutine f(x)
+ type(t) :: x[*]
+ if ( associated(x%z) ) deallocate(x%z)
+ end subroutine
+end program
+
Index: Fortran/gfortran/regression/coarray/ptr_comp_2.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/ptr_comp_2.f08
@@ -0,0 +1,36 @@
+! { dg-do run }
+
+program ptr_comp
+ type t
+ integer, pointer :: z(:)
+ end type
+ type(t), save :: obj[*]
+ integer, allocatable, target :: i(:)[:]
+
+ if (associated(obj%z)) error stop "'z' should not be associated yet."
+ allocate (obj%z(5))
+ call f(obj)
+ if (associated(obj%z)) error stop "'z' should not be associated anymore."
+
+ allocate(i(7)[*], SOURCE=42)
+ obj%z => i
+ if (.not. allocated(i)) error stop "'i' no longer allocated."
+ i = 15
+ if (any(obj%z(:) /= 15)) error stop "'obj%z' is deep copy and not pointer."
+
+ nullify (obj%z)
+ if (.not. allocated(i)) error stop "'i' should still be allocated."
+ if (associated(obj%z)) error stop "'obj%z' should not be associated anymore."
+
+ obj%z => i
+ call f(obj)
+ ! One can not say anything about i here. The memory should be deallocated, but
+ ! the pointer in i is still set.
+ if (associated(obj%z)) error stop "'obj%z' should not be associated anymore."
+contains
+ subroutine f(x)
+ type(t) :: x[*]
+ if ( associated(x%z) ) deallocate(x%z)
+ end subroutine
+end program
+
Index: Fortran/gfortran/regression/coarray/ptr_comp_3.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/ptr_comp_3.f08
@@ -0,0 +1,22 @@
+! { dg-do run }
+
+! Contributed by Damian Rouson
+! Same like coarray/alloc_comp_4
+
+program main
+
+ implicit none
+
+ type mytype
+ integer, pointer :: indices(:)
+ end type
+
+ type(mytype), save :: object[*]
+ integer :: me
+
+ me=this_image()
+ allocate(object%indices(me))
+ object%indices = 42
+
+ if ( any( object[me]%indices(:) /= 42 ) ) STOP 1
+end program
Index: Fortran/gfortran/regression/coarray/ptr_comp_4.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/ptr_comp_4.f08
@@ -0,0 +1,20 @@
+! { dg-do run }
+
+! Same like coarray/alloc_comp_5 but for pointer comp.
+
+program Jac
+ type Domain
+ integer :: n=64
+ integer, pointer :: endsi(:)
+ end type
+ type(Domain),allocatable :: D[:,:,:]
+
+ allocate(D[2,2,*])
+ allocate(D%endsi(2), source = 0)
+ ! No caf-runtime call needed her.
+ D%endsi(2) = D%n
+ if (any(D%endsi /= [ 0, 64])) error stop
+ deallocate(D%endsi)
+ deallocate(D)
+end program
+
Index: Fortran/gfortran/regression/coarray/registering_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/registering_1.f90
@@ -0,0 +1,41 @@
+! { dg-do run }
+!
+! PR fortran/18918
+!
+! Check whether registering coarrays works
+!
+module m
+ integer :: a(1)[*] = 7
+end module m
+
+use m
+if (any (a /= 7)) STOP 1
+a = 88
+if (any (a /= 88)) STOP 2
+
+ block
+ integer :: b[*] = 8494
+ if (b /= 8494) STOP 3
+ end block
+
+if (any (a /= 88)) STOP 4
+call test ()
+end
+
+subroutine test()
+ real :: z[*] = sqrt(2.0)
+ if (z /= sqrt(2.0)) STOP 5
+ call sub1()
+contains
+ subroutine sub1
+ real :: r[4,*] = -1
+ if (r /= -1) STOP 1
+ r = 10
+ if (r /= 10) STOP 2
+ end subroutine sub1
+
+ subroutine uncalled()
+ integer :: not_refed[2:*] = 784
+ if (not_refed /= 784) STOP 6
+ end subroutine uncalled
+end subroutine test
Index: Fortran/gfortran/regression/coarray/scalar_alloc_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/scalar_alloc_1.f90
@@ -0,0 +1,68 @@
+! { dg-do run }
+!
+implicit none
+integer, allocatable :: A[:], B[:,:]
+integer :: n1, n2, n3
+
+if (allocated (a)) STOP 1
+if (allocated (b)) STOP 2
+
+allocate(a[*])
+a = 5 + this_image ()
+if (a[this_image ()] /= 5 + this_image ()) STOP 1
+
+a[this_image ()] = 8 - 2*this_image ()
+if (a[this_image ()] /= 8 - 2*this_image ()) STOP 2
+
+if (lcobound(a, dim=1) /= 1 .or. ucobound(a,dim=1) /= num_images()) &
+ STOP 3
+deallocate(a)
+
+allocate(a[4:*])
+a[this_image ()] = 8 - 2*this_image ()
+
+if (lcobound(a, dim=1) /= 4 .or. ucobound(a,dim=1) /= 3 + num_images()) &
+ STOP 4
+
+n1 = -1
+n2 = 5
+n3 = 3
+allocate (B[n1:n2, n3:*])
+if (any (lcobound(b) /= [-1, 3]) .or. lcobound(B, dim=2) /= n3) &
+ STOP 5
+call sub(A, B)
+
+if (allocated (a)) STOP 6
+if (.not.allocated (b)) STOP 7
+
+call two(.true.)
+call two(.false.)
+
+! automatically deallocate "B"
+contains
+ subroutine sub(x, y)
+ integer, allocatable :: x[:], y[:,:]
+
+ if (any (lcobound(y) /= [-1, 3]) .or. lcobound(y, dim=2) /= n3) &
+ STOP 8
+ if (lcobound(x, dim=1) /= 4 .or. ucobound(x,dim=1) /= 3 + num_images()) &
+ STOP 9
+ if (x[this_image ()] /= 8 - 2*this_image ()) STOP 3
+ deallocate(x)
+ end subroutine sub
+
+ subroutine two(init)
+ logical, intent(in) :: init
+ integer, allocatable, SAVE :: a[:]
+
+ if (init) then
+ if (allocated(a)) STOP 10
+ allocate(a[*])
+ a = 45
+ else
+ if (.not. allocated(a)) STOP 11
+ if (a /= 45) STOP 12
+ deallocate(a)
+ end if
+ end subroutine two
+end
Index: Fortran/gfortran/regression/coarray/scalar_alloc_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/scalar_alloc_2.f90
@@ -0,0 +1,60 @@
+! { dg-do run }
+!
+! Check whether registering allocatable coarrays works
+!
+type position
+ real :: x, y, z
+end type position
+
+integer, allocatable :: a[:]
+type(position), allocatable :: p[:]
+
+allocate(a[*])
+a = 7
+
+allocate(p[*])
+p%x = 11
+p%y = 13
+p%z = 15
+
+if (a /= 7) STOP 1
+a = 88
+if (a /= 88) STOP 2
+
+if (p%x /= 11) STOP 3
+p%x = 17
+if (p%x /= 17) STOP 4
+
+ block
+ integer, allocatable :: b[:]
+
+ allocate(b[*])
+ b = 8494
+
+ if (b /= 8494) STOP 5
+ end block
+
+if (a /= 88) STOP 6
+call test ()
+end
+
+subroutine test()
+ type velocity
+ real :: x, y, z
+ end type velocity
+
+ real, allocatable :: z[:]
+ type(velocity), allocatable :: v[:]
+
+ allocate(z[*])
+ z = sqrt(2.0)
+
+ allocate(v[*])
+ v%x = 21
+ v%y = 23
+ v%z = 25
+
+ if (z /= sqrt(2.0)) STOP 7
+ if (v%x /= 21) STOP 8
+
+end subroutine test
Index: Fortran/gfortran/regression/coarray/send_array.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/send_array.f90
@@ -0,0 +1,407 @@
+! { dg-do run }
+!
+! This program does a correctness check for
+! ARRAY[idx] = SCALAR, ARRAY[idx] = ARRAY and SCALAR[idx] = SCALAR
+!
+program main
+ implicit none
+ integer, parameter :: n = 3
+ integer, parameter :: m = 4
+
+ ! Allocatable coarrays
+ call one(-5, 1)
+ call one(0, 0)
+ call one(1, -5)
+ call one(0, -11)
+
+ ! Static coarrays
+ call two()
+ call three()
+contains
+ subroutine one(lb1, lb2)
+ integer, value :: lb1, lb2
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, allocatable :: caf(:,:)[:]
+ integer, allocatable :: a(:,:), b(:,:)
+
+ allocate(caf(lb1:n+lb1-1, lb2:m+lb2-1)[*], &
+ a(lb1:n+lb1-1, lb2:m+lb2-1), &
+ b(lb1:n+lb1-1, lb2:m+lb2-1))
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = SCALAR
+ caf = -42
+ a = -42
+ a(:,:) = b(lb1, lb2)
+ sync all
+ if (this_image() == 1) then
+ caf(:,:)[num_images()] = b(lb1, lb2)
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 1
+ end if
+ sync all
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ a(:,:) = b(:, :)
+ sync all
+ if (this_image() == 1) then
+ caf(:,:)[num_images()] = b(:, :)
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 2
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, 1, -2
+ a(i,j) = b(i,j)
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = 1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ end do
+ end do
+ sync all
+ if (this_image() == 1) then
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, 1, -2
+ caf(i,j)[num_images()] = b(i, j)
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = 1, n+lb1-1, 2
+ caf(i,j)[num_images()] = b(i, j)
+ end do
+ end do
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 3
+ end if
+ sync all
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = SCALAR
+ caf = -42
+ a = -42
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) = b(lb1, lb2)
+ sync all
+ if (this_image() == 1) then
+ caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()] &
+ = b(lb1, lb2)
+ end if
+ sync all
+
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ sync all
+ if (this_image() == 1) then
+ caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()] &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ end if
+ sync all
+
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) then
+ print '(*(g0))', "bounds: ", lb1,":",n+lb1-1,", ", &
+ lb2,":",m+lb2-1
+ print '(*(g0))', "section: ", i,":",i_e,":",i_s*i_sgn1, &
+ ", ", j,":",j_e,":",j_s*i_sgn2
+ print *, i
+ print *, a
+ print *, caf
+ print *, a-caf
+ STOP 4
+ endif
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine one
+
+ subroutine two()
+ integer, parameter :: lb1 = -5, lb2 = 1
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, save :: caf(lb1:n+lb1-1, lb2:m+lb2-1)[*]
+ integer, save :: a(lb1:n+lb1-1, lb2:m+lb2-1)
+ integer, save :: b(lb1:n+lb1-1, lb2:m+lb2-1)
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = SCALAR
+ caf = -42
+ a = -42
+ a(:,:) = b(lb1, lb2)
+ sync all
+ if (this_image() == 1) then
+ caf(:,:)[num_images()] = b(lb1, lb2)
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 5
+ end if
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ a(:,:) = b(:, :)
+ sync all
+ if (this_image() == 1) then
+ caf(:,:)[num_images()] = b(:, :)
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 6
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, 1, -2
+ a(i,j) = b(i,j)
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = 1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ end do
+ end do
+ sync all
+ if (this_image() == 1) then
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, 1, -2
+ caf(i,j)[num_images()] = b(i, j)
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = 1, n+lb1-1, 2
+ caf(i,j)[num_images()] = b(i, j)
+ end do
+ end do
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 7
+ end if
+ sync all
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = SCALAR
+ caf = -42
+ a = -42
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) = b(lb1, lb2)
+ sync all
+ if (this_image() == 1) then
+ caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()] &
+ = b(lb1, lb2)
+ end if
+ sync all
+
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ sync all
+ if (this_image() == 1) then
+ caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()] &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ end if
+ sync all
+
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) then
+ print '(*(g0))', "bounds: ", lb1,":",n+lb1-1,", ", &
+ lb2,":",m+lb2-1
+ print '(*(g0))', "section: ", i,":",i_e,":",i_s*i_sgn1, &
+ ", ", j,":",j_e,":",j_s*i_sgn2
+ print *, i
+ print *, a
+ print *, caf
+ print *, a-caf
+ STOP 8
+ endif
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine two
+
+ subroutine three()
+ integer, parameter :: lb1 = 0, lb2 = 0
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, save :: caf(lb1:n+lb1-1, lb2:m+lb2-1)[*]
+ integer, save :: a(lb1:n+lb1-1, lb2:m+lb2-1)
+ integer, save :: b(lb1:n+lb1-1, lb2:m+lb2-1)
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = SCALAR
+ caf = -42
+ a = -42
+ a(:,:) = b(lb1, lb2)
+ sync all
+ if (this_image() == 1) then
+ caf(:,:)[num_images()] = b(lb1, lb2)
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 9
+ end if
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ a(:,:) = b(:, :)
+ sync all
+ if (this_image() == 1) then
+ caf(:,:)[num_images()] = b(:, :)
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 10
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, 1, -2
+ a(i,j) = b(i,j)
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = 1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ end do
+ end do
+ sync all
+ if (this_image() == 1) then
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, 1, -2
+ caf(i,j)[num_images()] = b(i, j)
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = 1, n+lb1-1, 2
+ caf(i,j)[num_images()] = b(i, j)
+ end do
+ end do
+ end if
+ sync all
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) &
+ STOP 11
+ end if
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = SCALAR
+ caf = -42
+ a = -42
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) = b(lb1, lb2)
+ sync all
+ if (this_image() == 1) then
+ caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()] &
+ = b(lb1, lb2)
+ end if
+ sync all
+
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ sync all
+ if (this_image() == 1) then
+ caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()] &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ end if
+ sync all
+
+ if (this_image() == num_images()) then
+ if (any (a /= caf)) then
+ print '(*(g0))', "bounds: ", lb1,":",n+lb1-1,", ", &
+ lb2,":",m+lb2-1
+ print '(*(g0))', "section: ", i,":",i_e,":",i_s*i_sgn1, &
+ ", ", j,":",j_e,":",j_s*i_sgn2
+ print *, i
+ print *, a
+ print *, caf
+ print *, a-caf
+ STOP 12
+ endif
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine three
+end program main
Index: Fortran/gfortran/regression/coarray/send_char_array_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/send_char_array_1.f90
@@ -0,0 +1,54 @@
+!{ dg-do run }
+
+program send_convert_char_array
+
+ implicit none
+
+ character(kind=1, len=:), allocatable, codimension[:] :: co_str_k1_scal
+ character(kind=1, len=:), allocatable :: str_k1_scal
+ character(kind=4, len=:), allocatable, codimension[:] :: co_str_k4_scal
+ character(kind=4, len=:), allocatable :: str_k4_scal
+
+ character(kind=1, len=:), allocatable, codimension[:] :: co_str_k1_arr(:)
+ character(kind=1, len=:), allocatable :: str_k1_arr(:)
+ character(kind=4, len=:), allocatable, codimension[:] :: co_str_k4_arr(:)
+ character(kind=4, len=:), allocatable :: str_k4_arr(:)
+
+ allocate(str_k1_scal, SOURCE='abcdefghij')
+ allocate(str_k4_scal, SOURCE=4_'abcdefghij')
+ allocate(character(len=20)::co_str_k1_scal[*]) ! allocate syncs here
+ allocate(character(kind=4, len=20)::co_str_k4_scal[*]) ! allocate syncs here
+
+ allocate(str_k1_arr, SOURCE=['abc', 'EFG', 'klm', 'NOP'])
+ allocate(str_k4_arr, SOURCE=[4_'abc', 4_'EFG', 4_'klm', 4_'NOP'])
+ allocate(character(len=5)::co_str_k1_arr(4)[*])
+ allocate(character(kind=4, len=5)::co_str_k4_arr(4)[*])
+
+ ! First check send/copy to self
+ co_str_k1_scal[this_image()] = str_k1_scal
+ if (co_str_k1_scal /= str_k1_scal // ' ') STOP 1
+
+ co_str_k4_scal[this_image()] = str_k4_scal
+ if (co_str_k4_scal /= str_k4_scal // 4_' ') STOP 2
+
+ co_str_k4_scal[this_image()] = str_k1_scal
+ if (co_str_k4_scal /= str_k4_scal // 4_' ') STOP 3
+
+ co_str_k1_scal[this_image()] = str_k4_scal
+ if (co_str_k1_scal /= str_k1_scal // ' ') STOP 4
+
+ co_str_k1_arr(:)[this_image()] = str_k1_arr
+ if (any(co_str_k1_arr /= ['abc ', 'EFG ', 'klm ', 'NOP '])) STOP 5
+
+ co_str_k4_arr(:)[this_image()] = [4_'abc', 4_'EFG', 4_'klm', 4_'NOP']! str_k4_arr
+ if (any(co_str_k4_arr /= [4_'abc ', 4_'EFG ', 4_'klm ', 4_'NOP '])) STOP 6
+
+ co_str_k4_arr(:)[this_image()] = str_k1_arr
+ if (any(co_str_k4_arr /= [ 4_'abc ', 4_'EFG ', 4_'klm ', 4_'NOP '])) STOP 7
+
+ co_str_k1_arr(:)[this_image()] = str_k4_arr
+ if (any(co_str_k1_arr /= ['abc ', 'EFG ', 'klm ', 'NOP '])) STOP 8
+
+end program send_convert_char_array
+
+! vim:ts=2:sts=2:sw=2:
Index: Fortran/gfortran/regression/coarray/sendget_array.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/sendget_array.f90
@@ -0,0 +1,288 @@
+! { dg-do run }
+!
+! This program does a correctness check for
+! ARRAY[idx] = ARRAY[idx] and SCALAR[idx] = SCALAR[idx]
+!
+
+
+!
+! FIXME: two/three has to be modified, test has to be checked and
+! diagnostic has to be removed
+!
+
+program main
+ implicit none
+ integer, parameter :: n = 3
+ integer, parameter :: m = 4
+
+ ! Allocatable coarrays
+ call one(-5, 1)
+ call one(0, 0)
+ call one(1, -5)
+ call one(0, -11)
+
+ ! Static coarrays
+ call two()
+ call three()
+contains
+ subroutine one(lb1, lb2)
+ integer, value :: lb1, lb2
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, allocatable :: caf(:,:)[:], caf2(:,:)[:]
+ integer, allocatable :: a(:,:), b(:,:)
+
+ allocate(caf(lb1:n+lb1-1, lb2:m+lb2-1)[*], &
+ caf2(lb1:n+lb1-1, lb2:m+lb2-1)[*], &
+ a(lb1:n+lb1-1, lb2:m+lb2-1), &
+ b(lb1:n+lb1-1, lb2:m+lb2-1))
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(:,:) = b(:,:)
+ caf2(:,:)[this_image()] = caf(:,:)[num_images()]
+ if (any (a /= caf2)) then
+ STOP 1
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, lb1, -2
+ a(i,j) = b(i,j)
+ caf2(i,j)[this_image()] = caf(i,j)[num_images()]
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = lb1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ caf2(i,j)[this_image()] = caf(i,j)[num_images()]
+ end do
+ end do
+ if (any (a /= caf2)) then
+ STOP 2
+ end if
+ sync all
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ caf2(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[this_image()] &
+ = caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()]
+ if (any (caf2 /= a)) then
+ STOP 3
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine one
+
+ subroutine two()
+ integer, parameter :: lb1 = -5, lb2 = 1
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, save :: caf(lb1:n+lb1-1, lb2:m+lb2-1)[*]
+ integer, save :: caf2(lb1:n+lb1-1, lb2:m+lb2-1)[*]
+ integer, save :: a(lb1:n+lb1-1, lb2:m+lb2-1)
+ integer, save :: b(lb1:n+lb1-1, lb2:m+lb2-1)
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(:,:) = b(:,:)
+ caf2(:,:)[this_image()] = caf(:,:)[num_images()]
+ if (any (a /= caf2)) then
+ STOP 4
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, lb1, -2
+ a(i,j) = b(i,j)
+ caf2(i,j)[this_image()] = caf(i,j)[num_images()]
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = lb1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ caf2(i,j)[this_image()] = caf(i,j)[num_images()]
+ end do
+ end do
+ if (any (a /= caf2)) then
+ STOP 5
+ end if
+ sync all
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ caf2(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[this_image()] &
+ = caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()]
+ if (any (caf2 /= a)) then
+ STOP 6
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine two
+
+ subroutine three()
+ integer, parameter :: lb1 = 0, lb2 = 0
+
+ integer :: i_sgn1, i_sgn2, i, i_e, i_s, j, j_e, j_s
+ integer, save :: caf(lb1:n+lb1-1, lb2:m+lb2-1)[*]
+ integer, save :: caf2(lb1:n+lb1-1, lb2:m+lb2-1)[*]
+ integer, save :: a(lb1:n+lb1-1, lb2:m+lb2-1)
+ integer, save :: b(lb1:n+lb1-1, lb2:m+lb2-1)
+
+ b = reshape([(i*33, i = 1, size(b))], shape(b))
+
+ ! Whole array: ARRAY = ARRAY
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(:,:) = b(:,:)
+ caf2(:,:)[this_image()] = caf(:,:)[num_images()]
+ if (any (a /= caf2)) then
+ STOP 7
+ end if
+ sync all
+
+ ! Scalar assignment
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ do j = lb2, m+lb2-1
+ do i = n+lb1-1, lb1, -2
+ a(i,j) = b(i,j)
+ caf2(i,j)[this_image()] = caf(i,j)[num_images()]
+ end do
+ end do
+ do j = lb2, m+lb2-1
+ do i = lb1, n+lb1-1, 2
+ a(i,j) = b(i,j)
+ caf2(i,j)[this_image()] = caf(i,j)[num_images()]
+ end do
+ end do
+ if (any (a /= caf2)) then
+ STOP 8
+ end if
+ sync all
+
+ ! Array sections with different ranges and pos/neg strides
+ do i_sgn1 = -1, 1, 2
+ do i_sgn2 = -1, 1, 2
+ do i=lb1, n+lb1-1
+ do i_e=lb1, n+lb1-1
+ do i_s=1, n
+ do j=lb2, m+lb2-1
+ do j_e=lb2, m+lb2-1
+ do j_s=1, m
+ ! ARRAY = ARRAY
+ caf = -42
+ a = -42
+ caf2 = -42
+ if (this_image() == num_images()) then
+ caf(:,:) = b(:,:)
+ endif
+ sync all
+ a(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2) &
+ = b(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)
+ caf2(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[this_image()] &
+ = caf(i:i_e:i_s*i_sgn1, j:j_e:j_s*i_sgn2)[num_images()]
+ if (any (caf2 /= a)) then
+ STOP 9
+ end if
+ sync all
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end subroutine three
+end program main
Index: Fortran/gfortran/regression/coarray/stopped_images_1.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/stopped_images_1.f08
@@ -0,0 +1,20 @@
+! { dg-do compile }
+
+program test_stopped_images_1
+ implicit none
+
+ integer, allocatable :: gi(:)
+ real :: r
+ integer :: i
+
+ gi = stopped_images() ! OK
+ gi = stopped_images(TEAM=1) ! { dg-error "'team' argument of 'stopped_images' intrinsic at \\(1\\) not yet supported" }
+ gi = stopped_images(KIND=1) ! OK
+ gi = stopped_images(KIND=4) ! OK
+ gi = stopped_images(KIND=0) ! { dg-error "'kind' argument of 'stopped_images' intrinsic at \\\(1\\\) must be positive" }
+ gi = stopped_images(KIND=r) ! { dg-error "'kind' argument of 'stopped_images' intrinsic at \\\(1\\\) must be INTEGER" }
+ gi = stopped_images(KIND=i) ! { dg-error "Constant expression required at \\\(1\\\)" }
+ gi = stopped_images(KIND=42) ! { dg-error "'kind' argument of 'stopped_images' intrinsic at \\\(1\\\) shall specify a valid integer kind" }
+
+end program test_stopped_images_1
+
Index: Fortran/gfortran/regression/coarray/stopped_images_2.f08
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/stopped_images_2.f08
@@ -0,0 +1,17 @@
+! { dg-do run }
+
+program test_stopped_images_2
+ implicit none
+
+ integer, allocatable :: si(:)
+ integer(kind=1), allocatable :: ssi(:)
+
+ si = stopped_images()
+ if (size(si) > 0) error stop "stopped_images result shall be empty array"
+ ssi = stopped_images(KIND=1)
+ if (size(ssi) > 0) error stop "stopped_images result shall be empty array"
+ ssi = stopped_images(KIND=8)
+ if (size(ssi) > 0) error stop "stopped_images result shall be empty array"
+
+end program test_stopped_images_2
+
Index: Fortran/gfortran/regression/coarray/subobject_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/subobject_1.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+!
+! PR fortran/50420
+! Coarray subobjects were not accepted as valid coarrays
+
+ integer :: i
+ integer, parameter :: la = 4, lb = 5, lc = 8
+ integer, parameter :: init(la) = -4 + (/ (i, i=1,la) /)
+
+ type t
+ integer :: i
+ end type t
+ type t2
+ type(t), allocatable :: a[:]
+ end type t2
+ type t3
+ type(t), allocatable :: a(:)[:]
+ end type t3
+
+ type(t2) :: b
+ type(t3) :: c
+
+ allocate(b%a[lb:*])
+ b%a%i = 7
+ if (b%a%i /= 7) STOP 1
+ if (any (lcobound(b%a) /= (/ lb /))) STOP 2
+ if (ucobound(b%a, dim=1) /= num_images() + lb - 1) STOP 3
+ if (any (lcobound(b%a%i) /= (/ lb /))) STOP 4
+ if (ucobound(b%a%i, dim=1) /= num_images() + lb - 1) STOP 5
+ allocate(c%a(la)[lc:*])
+ c%a%i = init
+ if (any(c%a%i /= init)) STOP 6
+ if (any (lcobound(c%a) /= (/ lc /))) STOP 7
+ if (ucobound(c%a, dim=1) /= num_images() + lc - 1) STOP 8
+ if (any (lcobound(c%a%i) /= (/ lc /))) STOP 9
+ if (ucobound(c%a%i, dim=1) /= num_images() + lc - 1) STOP 10
+ if (c%a(2)%i /= init(2)) STOP 11
+ if (any (lcobound(c%a(2)) /= (/ lc /))) STOP 12
+ if (ucobound(c%a(2), dim=1) /= num_images() + lc - 1) STOP 13
+ if (any (lcobound(c%a(2)%i) /= (/ lc /))) STOP 14
+ if (ucobound(c%a(2)%i, dim=1) /= num_images() + lc - 1) STOP 15
+ deallocate(b%a, c%a)
+end
Index: Fortran/gfortran/regression/coarray/sync_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/sync_1.f90
@@ -0,0 +1,64 @@
+! { dg-do run }
+!
+! Coarray support
+! PR fortran/18918
+
+implicit none
+integer :: n
+character(len=30) :: str
+critical
+end critical
+myCr: critical
+end critical myCr
+
+!
+! Test SYNC ALL
+!
+sync all
+sync all ( )
+sync all (errmsg=str)
+
+n = 5
+sync all (stat=n)
+if (n /= 0) STOP 1
+
+n = 5
+sync all (stat=n,errmsg=str)
+if (n /= 0) STOP 2
+
+
+!
+! Test SYNC MEMORY
+!
+sync memory
+sync memory ( )
+sync memory (errmsg=str)
+
+n = 5
+sync memory (stat=n)
+if (n /= 0) STOP 3
+
+n = 5
+sync memory (errmsg=str,stat=n)
+if (n /= 0) STOP 4
+
+
+!
+! Test SYNC IMAGES
+!
+sync images (*)
+if (this_image() == 1) then
+ sync images (1)
+ sync images (1, errmsg=str)
+ sync images ([1])
+end if
+
+n = 5
+sync images (*, stat=n)
+if (n /= 0) STOP 5
+
+n = 5
+sync images (*,errmsg=str,stat=n)
+if (n /= 0) STOP 6
+
+end
Index: Fortran/gfortran/regression/coarray/sync_3.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/sync_3.f90
@@ -0,0 +1,75 @@
+! { dg-do run }
+! { dg-options "-fcheck=all" }
+! { dg-shouldfail "Invalid image number -1 in SYNC IMAGES" }
+!
+! As sync_1, but with bounds checking enabled.
+! PR fortran/52161
+!
+! Coarray support
+! PR fortran/18918
+
+implicit none
+integer :: n
+character(len=30) :: str
+critical
+end critical
+myCr: critical
+end critical myCr
+
+!
+! Test SYNC ALL
+!
+sync all
+sync all ( )
+sync all (errmsg=str)
+
+n = 5
+sync all (stat=n)
+if (n /= 0) STOP 1
+
+n = 5
+sync all (stat=n,errmsg=str)
+if (n /= 0) STOP 2
+
+
+!
+! Test SYNC MEMORY
+!
+sync memory
+sync memory ( )
+sync memory (errmsg=str)
+
+n = 5
+sync memory (stat=n)
+if (n /= 0) STOP 3
+
+n = 5
+sync memory (errmsg=str,stat=n)
+if (n /= 0) STOP 4
+
+
+!
+! Test SYNC IMAGES
+!
+sync images (*)
+if (this_image() == 1) then
+ sync images (1)
+ sync images (1, errmsg=str)
+ sync images ([1])
+end if
+
+n = 5
+sync images (*, stat=n)
+if (n /= 0) STOP 5
+
+n = 5
+sync images (*,errmsg=str,stat=n)
+if (n /= 0) STOP 6
+
+n = -1
+sync images ( num_images() )
+sync images (n) ! Invalid: "-1"
+
+end
+
+! { dg-output "Fortran runtime error: Invalid image number -1 in SYNC IMAGES" }
Index: Fortran/gfortran/regression/coarray/this_image_1.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/this_image_1.f90
@@ -0,0 +1,196 @@
+! { dg-do run }
+!
+! PR fortran/18918
+!
+! this_image(coarray) run test,
+! expecially for num_images > 1
+!
+! Tested are values up to num_images == 8,
+! higher values are OK, but not tested for
+!
+implicit none
+integer :: a(1)[2:2, 3:4, 7:*]
+integer :: b(:)[:, :,:]
+allocatable :: b
+integer :: i
+
+if (this_image(A, dim=1) /= 2) STOP 1
+i = 1
+if (this_image(A, dim=i) /= 2) STOP 2
+
+select case (this_image())
+ case (1)
+ if (this_image(A, dim=2) /= 3) STOP 3
+ if (this_image(A, dim=3) /= 7) STOP 4
+ i = 2
+ if (this_image(A, dim=i) /= 3) STOP 5
+ i = 3
+ if (this_image(A, dim=i) /= 7) STOP 6
+ if (any (this_image(A) /= [2,3,7])) STOP 7
+
+ case (2)
+ if (this_image(A, dim=2) /= 4) STOP 8
+ if (this_image(A, dim=3) /= 7) STOP 9
+ i = 2
+ if (this_image(A, dim=i) /= 4) STOP 10
+ i = 3
+ if (this_image(A, dim=i) /= 7) STOP 11
+ if (any (this_image(A) /= [2,4,7])) STOP 12
+
+ case (3)
+ if (this_image(A, dim=2) /= 3) STOP 13
+ if (this_image(A, dim=3) /= 8) STOP 14
+ i = 2
+ if (this_image(A, dim=i) /= 3) STOP 15
+ i = 3
+ if (this_image(A, dim=i) /= 8) STOP 16
+ if (any (this_image(A) /= [2,3,8])) STOP 17
+
+ case (4)
+ if (this_image(A, dim=2) /= 4) STOP 18
+ if (this_image(A, dim=3) /= 8) STOP 19
+ i = 2
+ if (this_image(A, dim=i) /= 4) STOP 20
+ i = 3
+ if (this_image(A, dim=i) /= 8) STOP 21
+ if (any (this_image(A) /= [2,4,8])) STOP 22
+
+ case (5)
+ if (this_image(A, dim=2) /= 3) STOP 23
+ if (this_image(A, dim=3) /= 9) STOP 24
+ i = 2
+ if (this_image(A, dim=i) /= 3) STOP 25
+ i = 3
+ if (this_image(A, dim=i) /= 9) STOP 26
+ if (any (this_image(A) /= [2,3,9])) STOP 27
+
+ case (6)
+ if (this_image(A, dim=2) /= 4) STOP 28
+ if (this_image(A, dim=3) /= 9) STOP 29
+ i = 2
+ if (this_image(A, dim=i) /= 4) STOP 30
+ i = 3
+ if (this_image(A, dim=i) /= 9) STOP 31
+ if (any (this_image(A) /= [2,4,9])) STOP 32
+
+ case (7)
+ if (this_image(A, dim=2) /= 3) STOP 33
+ if (this_image(A, dim=3) /= 10) STOP 34
+ i = 2
+ if (this_image(A, dim=i) /= 3) STOP 35
+ i = 3
+ if (this_image(A, dim=i) /= 10) STOP 36
+ if (any (this_image(A) /= [2,3,10])) STOP 37
+
+ case (8)
+ if (this_image(A, dim=2) /= 4) STOP 38
+ if (this_image(A, dim=3) /= 10) STOP 39
+ i = 2
+ if (this_image(A, dim=i) /= 4) STOP 40
+ i = 3
+ if (this_image(A, dim=i) /= 10) STOP 41
+ if (any (this_image(A) /= [2,4,10])) STOP 42
+end select
+
+
+allocate (b(3)[-1:0,2:4,*])
+
+select case (this_image())
+ case (1)
+ if (this_image(B, dim=1) /= -1) STOP 43
+ if (this_image(B, dim=2) /= 2) STOP 44
+ if (this_image(B, dim=3) /= 1) STOP 45
+ i = 1
+ if (this_image(B, dim=i) /= -1) STOP 46
+ i = 2
+ if (this_image(B, dim=i) /= 2) STOP 47
+ i = 3
+ if (this_image(B, dim=i) /= 1) STOP 48
+ if (any (this_image(B) /= [-1,2,1])) STOP 49
+
+ case (2)
+ if (this_image(B, dim=1) /= 0) STOP 50
+ if (this_image(B, dim=2) /= 2) STOP 51
+ if (this_image(B, dim=3) /= 1) STOP 52
+ i = 1
+ if (this_image(B, dim=i) /= 0) STOP 53
+ i = 2
+ if (this_image(B, dim=i) /= 2) STOP 54
+ i = 3
+ if (this_image(B, dim=i) /= 1) STOP 55
+ if (any (this_image(B) /= [0,2,1])) STOP 56
+
+ case (3)
+ if (this_image(B, dim=1) /= -1) STOP 57
+ if (this_image(B, dim=2) /= 3) STOP 58
+ if (this_image(B, dim=3) /= 1) STOP 59
+ i = 1
+ if (this_image(B, dim=i) /= -1) STOP 60
+ i = 2
+ if (this_image(B, dim=i) /= 3) STOP 61
+ i = 3
+ if (this_image(B, dim=i) /= 1) STOP 62
+ if (any (this_image(B) /= [-1,3,1])) STOP 63
+
+ case (4)
+ if (this_image(B, dim=1) /= 0) STOP 64
+ if (this_image(B, dim=2) /= 3) STOP 65
+ if (this_image(B, dim=3) /= 1) STOP 66
+ i = 1
+ if (this_image(B, dim=i) /= 0) STOP 67
+ i = 2
+ if (this_image(B, dim=i) /= 3) STOP 68
+ i = 3
+ if (this_image(B, dim=i) /= 1) STOP 69
+ if (any (this_image(B) /= [0,3,1])) STOP 70
+
+ case (5)
+ if (this_image(B, dim=1) /= -1) STOP 71
+ if (this_image(B, dim=2) /= 4) STOP 72
+ if (this_image(B, dim=3) /= 1) STOP 73
+ i = 1
+ if (this_image(B, dim=i) /= -1) STOP 74
+ i = 2
+ if (this_image(B, dim=i) /= 4) STOP 75
+ i = 3
+ if (this_image(B, dim=i) /= 1) STOP 76
+ if (any (this_image(B) /= [-1,4,1])) STOP 77
+
+ case (6)
+ if (this_image(B, dim=1) /= 0) STOP 78
+ if (this_image(B, dim=2) /= 4) STOP 79
+ if (this_image(B, dim=3) /= 1) STOP 80
+ i = 1
+ if (this_image(B, dim=i) /= 0) STOP 81
+ i = 2
+ if (this_image(B, dim=i) /= 4) STOP 82
+ i = 3
+ if (this_image(B, dim=i) /= 1) STOP 83
+ if (any (this_image(B) /= [0,4,1])) STOP 84
+
+ case (7)
+ if (this_image(B, dim=1) /= -1) STOP 85
+ if (this_image(B, dim=2) /= 2) STOP 86
+ if (this_image(B, dim=3) /= 2) STOP 87
+ i = 1
+ if (this_image(B, dim=i) /= -1) STOP 88
+ i = 2
+ if (this_image(B, dim=i) /= 2) STOP 89
+ i = 3
+ if (this_image(B, dim=i) /= 2) STOP 90
+ if (any (this_image(B) /= [-1,2,2])) STOP 91
+
+ case (8)
+ if (this_image(B, dim=1) /= 0) STOP 92
+ if (this_image(B, dim=2) /= 2) STOP 93
+ if (this_image(B, dim=3) /= 2) STOP 94
+ i = 1
+ if (this_image(B, dim=i) /= 0) STOP 95
+ i = 2
+ if (this_image(B, dim=i) /= 2) STOP 96
+ i = 3
+ if (this_image(B, dim=i) /= 2) STOP 97
+ if (any (this_image(B) /= [0,2,2])) STOP 98
+end select
+
+end
Index: Fortran/gfortran/regression/coarray/this_image_2.f90
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/coarray/this_image_2.f90
@@ -0,0 +1,125 @@
+! { dg-do run }
+!
+! PR fortran/18918
+!
+! Version for scalar coarrays
+!
+! this_image(coarray) run test,
+! expecially for num_images > 1
+!
+! Tested are values up to num_images == 8,
+! higher values are OK, but not tested for
+!
+implicit none
+integer :: a[2:2, 3:4, 7:*]
+integer :: i
+
+if (this_image(A, dim=1) /= 2) STOP 1
+i = 1
+if (this_image(A, dim=i) /= 2) STOP 2
+
+select case (this_image())
+ case (1)
+ if (this_image(A, dim=2) /= 3) STOP 3
+ if (this_image(A, dim=3) /= 7) STOP 4
+ i = 2
+ if (this_image(A, dim=i) /= 3) STOP 5
+ i = 3
+ if (this_image(A, dim=i) /= 7) STOP 6
+ if (any (this_image(A) /= [2,3,7])) STOP 7
+
+ case (2)
+ if (this_image(A, dim=2) /= 4) STOP 8
+ if (this_image(A, dim=3) /= 7) STOP 9
+ i = 2
+ if (this_image(A, dim=i) /= 4) STOP 10
+ i = 3
+ if (this_image(A, dim=i) /= 7) STOP 11
+ if (any (this_image(A) /= [2,4,7])) STOP 12
+
+ case (3)
+ if (this_image(A, dim=2) /= 3) STOP 13
+ if (this_image(A, dim=3) /= 8) STOP 14
+ i = 2
+ if (this_image(A, dim=i) /= 3) STOP 15
+ i = 3
+ if (this_image(A, dim=i) /= 8) STOP 16
+ if (any (this_image(A) /= [2,3,8])) STOP 17
+
+ case (4)
+ if (this_image(A, dim=2) /= 4) STOP 18
+ if (this_image(A, dim=3) /= 8) STOP 19
+ i = 2
+ if (this_image(A, dim=i) /= 4) STOP 20
+ i = 3
+ if (this_image(A, dim=i) /= 8) STOP 21
+ if (any (this_image(A) /= [2,4,8])) STOP 22
+
+ case (5)
+ if (this_image(A, dim=2) /= 3) STOP 23
+ if (this_image(A, dim=3) /= 9) STOP 24
+ i = 2
+ if (this_image(A, dim=i) /= 3) STOP 25
+ i = 3
+ if (this_image(A, dim=i) /= 9) STOP 26
+ if (any (this_image(A) /= [2,3,9])) STOP 27
+
+ case (6)
+ if (this_image(A, dim=2) /= 4) STOP 28
+ if (this_image(A, dim=3) /= 9) STOP 29
+ i = 2
+ if (this_image(A, dim=i) /= 4) STOP 30
+ i = 3
+ if (this_image(A, dim=i) /= 9) STOP 31
+ if (any (this_image(A) /= [2,4,9])) STOP 32
+
+ case (7)
+ if (this_image(A, dim=2) /= 3) STOP 33
+ if (this_image(A, dim=3) /= 10) STOP 34
+ i = 2
+ if (this_image(A, dim=i) /= 3) STOP 35
+ i = 3
+ if (this_image(A, dim=i) /= 10) STOP 36
+ if (any (this_image(A) /= [2,3,10])) STOP 37
+
+ case (8)
+ if (this_image(A, dim=2) /= 4) STOP 38
+ if (this_image(A, dim=3) /= 10) STOP 39
+ i = 2
+ if (this_image(A, dim=i) /= 4) STOP 40
+ i = 3
+ if (this_image(A, dim=i) /= 10) STOP 41
+ if (any (this_image(A) /= [2,4,10])) STOP 42
+end select
+
+contains
+
+subroutine test_image_index
+implicit none
+integer :: index1, index2, index3
+logical :: one
+
+integer, save :: d(2)[-1:3, *]
+integer, save :: e(2)[-1:-1, 3:*]
+
+one = num_images() == 1
+
+index1 = image_index(d, [-1, 1] )
+index2 = image_index(d, [0, 1] )
+
+if (one .and. (index1 /= 1 .or. index2 /= 0)) &
+ STOP 43
+if (.not. one .and. (index1 /= 1 .or. index2 /= 2)) &
+ STOP 44
+
+index1 = image_index(e, [-1, 3] )
+index2 = image_index(e, [-1, 4] )
+
+if (one .and. (index1 /= 1 .or. index2 /= 0)) &
+ STOP 45
+if (.not. one .and. (index1 /= 1 .or. index2 /= 2)) &
+ STOP 46
+
+end subroutine test_image_index
+
+end
Index: Fortran/gfortran/regression/debug/debug.exp
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/debug/debug.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 2008-2023 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# .
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gfortran-dg.exp
+load_lib gfortran.exp
+
+# Debugging testsuite proc
+proc gfortran-debug-dg-test { prog do_what extra_tool_flags } {
+ return [gfortran-dg-test $prog $do_what $extra_tool_flags]
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+
+gfortran_init
+
+gfortran-dg-debug-runtest gfortran_target_compile trivial.f "" \
+ [lsort [glob -nocomplain $srcdir/$subdir/*.\[fS\]]]
+
+# All done.
+dg-finish
Index: Fortran/gfortran/regression/debug/pr35154-dwarf2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/debug/pr35154-dwarf2.f
@@ -0,0 +1,38 @@
+C Test program for common block debugging. G. Helffrich 11 July 2004.
+C { dg-do compile }
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "*" } { "-gdwarf-2" } }
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "-g1" } { "" } }
+C { dg-options "-dA -gno-strict-dwarf" }
+ common i,j
+ common /label/l,m
+ i = 1
+ j = 2
+ k = 3
+ l = 4
+ m = 5
+ call sub
+ end
+ subroutine sub
+ common /label/l,m
+ logical first
+ save n
+ data first /.true./
+ if (first) then
+ n = 0
+ first = .false.
+ endif
+ n = n + 1
+ l = l + 1
+ return
+ end
+
+C { dg-final { scan-assembler "DIE\[^\n\]*DW_TAG_common_block" } }
+C { dg-final { scan-assembler "(DW_AT_name: \"__BLNK__\"|\"__BLNK__\[^\n\]*\"\[^\n\]*DW_AT_name)" } }
+C { dg-final { scan-assembler "DIE\[^\n\]*DW_TAG_variable" } }
+C { dg-final { scan-assembler "\"i\[^\n\]*\"\[^\n\]*DW_AT_name" } }
+C { dg-final { scan-assembler "\"j\[^\n\]*\"\[^\n\]*DW_AT_name" } }
+C { dg-final { scan-assembler "DIE\[^\n\]*DW_TAG_common_block" } }
+C { dg-final { scan-assembler "(DW_AT_name: \"label\"|\"label\[^\n\]*\"\[^\n\]*DW_AT_name)" } }
+C { dg-final { scan-assembler "DIE\[^\n\]*DW_TAG_variable" } }
+C { dg-final { scan-assembler "\"l\[^\n\]*\"\[^\n\]*DW_AT_name" } }
+C { dg-final { scan-assembler "\"m\[^\n\]*\"\[^\n\]*DW_AT_name" } }
Index: Fortran/gfortran/regression/debug/pr37738.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/debug/pr37738.f
@@ -0,0 +1,31 @@
+C PR debug/37738
+C { dg-do compile }
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "*" } { "-gdwarf-2" } }
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "-g1" } { "" } }
+C { dg-options "-dA -gno-strict-dwarf" }
+
+ subroutine a
+ integer*4 a_i, c_i
+ common /block/a_i, c_i
+ a_i = 1
+ c_i = 4
+ end subroutine a
+ subroutine b
+ integer*4 b_i
+ common /block/b_i, d_i
+ b_i = 2
+ d_i = 5
+ end subroutine b
+ subroutine c
+ integer*4 a_i, c_i
+ common /block/a_i, c_i
+ if (a_i .ne. 2) STOP 1
+ if (c_i .ne. 5) STOP 2
+ end subroutine c
+ program abc
+ call a
+ call b
+ call c
+ end program abc
+
+C { dg-final { scan-assembler-times "DIE\[^\n\]*DW_TAG_common_block" 3 } }
Index: Fortran/gfortran/regression/debug/pr43166.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/debug/pr43166.f
@@ -0,0 +1,14 @@
+C PR debug/43166
+C { dg-do compile }
+C { dg-options "-O" }
+ SUBROUTINE FOO ()
+ INTEGER V1
+ COMMON // V1
+ END
+ SUBROUTINE BAR ()
+ INTEGER V0,V1,V2,V3
+ COMMON // V1(4),V2(85,4),V3
+ DO V3=1,V1(1)
+ V0=V2(V3,1)
+ END DO
+ END
Index: Fortran/gfortran/regression/debug/pr46756.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/debug/pr46756.f
@@ -0,0 +1,30 @@
+C PR debug/46756, reduced from ../20010519-1.f
+C { dg-do compile }
+C { dg-options "-O -fcompare-debug" }
+
+ LOGICAL QDISK,QDW,QCMPCT
+ LOGICAL LNOMA,LRAISE,LSCI,LBIG
+ ASSIGN 801 TO I800 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" }
+ GOTO 800
+ 801 CONTINUE
+ ASSIGN 761 TO I760 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" }
+ 761 CONTINUE
+ IF(LSCI) THEN
+ DO I=1,LENCM
+ ENDDO
+ ENDIF
+ DO WHILE((CVGMX.GT.TOLDIM).AND.(ITER.LT.ITMX))
+ IF(.NOT.QDW) THEN
+ ASSIGN 641 to I640 ! { dg-warning "Deleted feature: ASSIGN" "Deleted feature: ASSIGN" }
+ GOTO 640
+ 641 CONTINUE
+ ENDIF
+ ENDDO
+ GOTO 700
+ 640 CONTINUE
+ GOTO I640 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" }
+ 700 CONTINUE
+ GOTO I760 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" }
+ 800 CONTINUE
+ GOTO I800 ! { dg-warning "Deleted feature: Assigned" "Assigned GO TO" }
+ END
Index: Fortran/gfortran/regression/debug/trivial.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/debug/trivial.f
@@ -0,0 +1,2 @@
+ program trivial
+ end
Index: Fortran/gfortran/regression/g77/12002.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/12002.f
@@ -0,0 +1,6 @@
+C PR middle-end/12002
+C { dg-do compile }
+ COMPLEX TE1
+ TE1=-2.
+ TE1=TE1+TE1
+ END
Index: Fortran/gfortran/regression/g77/12632.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/12632.f
@@ -0,0 +1,6 @@
+C { dg-do compile }
+C { dg-options "-fbounds-check" }
+ INTEGER I(1)
+ I(2) = 0 ! { dg-warning "out of bounds" "out of bounds" }
+ END
+
Index: Fortran/gfortran/regression/g77/13037.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/13037.f
@@ -0,0 +1,59 @@
+c { dg-do run }
+c PR optimization/13037
+c Contributed by Kirill Smelkov
+c bug symptom: zeta(kkzc) seems to reference to zeta(kkzc-1) instead
+c with gcc-3.2.2 it is OK, so it is a regression.
+c
+ subroutine bug1(expnt)
+ implicit none
+
+ double precision zeta
+ common /bug1_area/zeta(3)
+
+ double precision expnt(3)
+
+
+ integer k, kkzc
+
+ kkzc=0
+ do k=1,3
+ kkzc = kkzc + 1
+ zeta(kkzc) = expnt(k)
+ enddo
+
+c the following line activates the bug
+ call bug1_activator(kkzc)
+ end
+
+
+c dummy subroutine
+ subroutine bug1_activator(inum)
+ implicit none
+ integer inum
+ end
+
+
+c test driver
+ program test_bug1
+ implicit none
+
+ double precision zeta
+ common /bug1_area/zeta(3)
+
+ double precision expnt(3)
+
+ zeta(1) = 0.0d0
+ zeta(2) = 0.0d0
+ zeta(3) = 0.0d0
+
+ expnt(1) = 1.0d0
+ expnt(2) = 2.0d0
+ expnt(3) = 3.0d0
+
+ call bug1(expnt)
+ if ((zeta(1).ne.1) .or. (zeta(2).ne.2) .or. (zeta(3).ne.3)) then
+ STOP 1
+ endif
+
+ end
+
Index: Fortran/gfortran/regression/g77/13060.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/13060.f
@@ -0,0 +1,14 @@
+c { dg-do compile }
+ subroutine geo2()
+ implicit none
+
+ integer ms,n,ne(2)
+
+ ne(1) = 1
+ ne(2) = 2
+ ms = 1
+
+ call call_me(ne(1)*ne(1))
+
+ n = ne(ms)
+ end
Index: Fortran/gfortran/regression/g77/1832.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/1832.f
@@ -0,0 +1,9 @@
+c { dg-do run }
+! { dg-options "-std=legacy" }
+!
+ character*5 string
+ write(string, *) "a "
+ if (string .ne. ' a') STOP 1
+C-- The leading space is normal for list-directed output
+
+ end
Index: Fortran/gfortran/regression/g77/19981119-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19981119-0.f
@@ -0,0 +1,41 @@
+c { dg-do run }
+* X-Delivered: at request of burley on mescaline.gnu.org
+* Date: Sat, 31 Oct 1998 18:26:29 +0200 (EET)
+* From: "B. Yanchitsky"
+* To: fortran@gnu.org
+* Subject: Bug report
+* MIME-Version: 1.0
+* Content-Type: TEXT/PLAIN; charset=US-ASCII
+*
+* There is a trouble with g77 on Alpha.
+* My configuration:
+* Digital Personal Workstation 433au,
+* Digital Unix 4.0D,
+* GNU Fortran 0.5.23 and GNU C 2.8.1.
+*
+* The following program treated successfully but crashed when running.
+*
+* C --- PROGRAM BEGIN -------
+*
+ subroutine sub(N,u)
+ integer N
+ double precision u(-N:N,-N:N)
+
+C vvvv CRASH HERE vvvvv
+ u(-N,N)=0d0
+ return
+ end
+
+
+ program bug
+ integer N
+ double precision a(-10:10,-10:10)
+ data a/441*1d0/
+ N=10
+ call sub(N,a)
+ if (a(-N,N) .ne. 0d0) STOP 1
+ end
+*
+* C --- PROGRAM END -------
+*
+* Good luck!
Index: Fortran/gfortran/regression/g77/19981216-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19981216-0.f
@@ -0,0 +1,92 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+c
+* Resent-From: Craig Burley
+* Resent-To: craig@jcb-sc.com
+* X-Delivered: at request of burley on mescaline.gnu.org
+* Date: Wed, 16 Dec 1998 18:31:24 +0100
+* From: Dieter Stueken
+* Organization: con terra GmbH
+* To: fortran@gnu.org
+* Subject: possible bug
+* Content-Type: text/plain; charset=iso-8859-1
+* X-Mime-Autoconverted: from 8bit to quoted-printable by mescaline.gnu.org id KAA09085
+* X-UIDL: 72293bf7f9fac8378ec7feca2bccbce2
+*
+* Hi,
+*
+* I'm about to compile a very old, very ugly Fortran program.
+* For one part I got:
+*
+* f77: Internal compiler error: program f771 got fatal signal 6
+*
+* instead of any detailed error message. I was able to break down the
+* problem to the following source fragment:
+*
+* -------------------------------------------
+ PROGRAM WAP
+
+ integer(kind=8) ios
+ character*80 name
+
+ name = 'blah'
+ open(unit=8,status='unknown',file=name,form='formatted',
+ F iostat=ios)
+
+ END
+* -------------------------------------------
+*
+* The problem seems to be caused by the "integer(kind=2) ios" declaration.
+* So far I solved it by simply using a plain integer instead.
+*
+* I'm running gcc on a Linux system compiled/installed
+* with no special options:
+*
+* -> g77 -v
+* g77 version 0.5.23
+* Driving: g77 -v -c -xf77-version /dev/null -xnone
+* Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnulibc1/2.8.1/specs
+* gcc version 2.8.1
+* /usr/lib/gcc-lib/i686-pc-linux-gnulibc1/2.8.1/cpp -lang-c -v -undef
+* -D__GNUC__=2 -D__GNUC_MINOR__=8 -D__ELF__ -D__unix__ -D__linux__
+* -D__unix -D__linux -Asystem(posix) -D_LANGUAGE_FORTRAN -traditional
+* -Di386 -Di686 -Asystem(unix) -Acpu(i386) -Amachine(i386) -D__i386__
+* -D__i686__ -Asystem(unix) -Acpu(i386) -Amachine(i386) /dev/null
+* /dev/null
+* GNU CPP version 2.8.1 (i386 GNU/Linux with ELF)
+* #include "..." search starts here:
+* #include <...> search starts here:
+* /usr/local/include
+* /usr/i686-pc-linux-gnulibc1/include
+* /usr/lib/gcc-lib/i686-pc-linux-gnulibc1/2.8.1/include
+* /usr/include
+* End of search list.
+* /usr/lib/gcc-lib/i686-pc-linux-gnulibc1/2.8.1/f771 -fnull-version
+* -quiet -dumpbase g77-version.f -version -fversion -o /tmp/cca24911.s
+* /dev/null
+* GNU F77 version 2.8.1 (i686-pc-linux-gnulibc1) compiled by GNU C version
+* 2.8.1.
+* GNU Fortran Front End version 0.5.23
+* as -V -Qy -o /tmp/cca24911.o /tmp/cca24911.s
+* GNU assembler version 2.8.1 (i486-linux), using BFD version 2.8.1
+* ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.1 -o /tmp/cca24911
+* /tmp/cca24911.o /usr/lib/crt1.o /usr/lib/crti.o
+* /usr/lib/gcc-lib/i686-pc-linux-gnulibc1/2.8.1/crtbegin.o
+* -L/usr/lib/gcc-lib/i686-pc-linux-gnulibc1/2.8.1 -L/usr -lg2c -lm -lgcc
+* -lc -lgcc /usr/lib/gcc-lib/i686-pc-linux-gnulibc1/2.8.1/crtend.o
+* /usr/lib/crtn.o
+* /tmp/cca24911
+* __G77_LIBF77_VERSION__: 0.5.23
+* @(#)LIBF77 VERSION 19970919
+* __G77_LIBI77_VERSION__: 0.5.23
+* @(#) LIBI77 VERSION pjw,dmg-mods 19980405
+* __G77_LIBU77_VERSION__: 0.5.23
+* @(#) LIBU77 VERSION 19970919
+*
+*
+* Regards, Dieter.
+* --
+* Dieter Stüken, con terra GmbH, Münster
+* stueken@conterra.de stueken@qgp.uni-muenster.de
+* http://www.conterra.de/ http://qgp.uni-muenster.de/~stueken
+* (0)251-980-2027 (0)251-83-334974
Index: Fortran/gfortran/regression/g77/19990218-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990218-0.f
@@ -0,0 +1,14 @@
+c { dg-do compile }
+ program test
+ double precision a,b,c
+ data a,b/1.0d-46,1.0d0/
+ c=fun(a,b) ! { dg-error "Return type mismatch of function" }
+ print*,'in main: fun=',c
+ end
+ double precision function fun(a,b)
+ double precision a,b
+ print*,'in sub: a,b=',a,b
+ fun=a*b
+ print*,'in sub: fun=',fun
+ return
+ end
Index: Fortran/gfortran/regression/g77/19990218-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990218-1.f
@@ -0,0 +1,25 @@
+c { dg-do compile }
+c
+c g77 used to warn for this case
+c 19990218-1.f: In program `test':
+c 19990218-1.f:13:
+c double precision function fun(a,b)
+c 1
+c 19990218-1.f:23: (continued):
+c c=fun(a,b)
+c 2
+c Global name `fun' at (2) has different type at (1) [info -f g77 M GLOBALS]
+c
+ double precision function fun(a,b)
+ double precision a,b
+ print*,'in sub: a,b=',a,b
+ fun=a*b
+ print*,'in sub: fun=',fun
+ return
+ end
+ program test
+ double precision a,b,c
+ data a,b/1.0d-46,1.0d0/
+ c=fun(a,b) ! { dg-error "Return type mismatch of function" }
+ print*,'in main: fun=',c
+ end
Index: Fortran/gfortran/regression/g77/19990305-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990305-0.f
@@ -0,0 +1,56 @@
+c { dg-do compile }
+* Date: Fri, 5 Mar 1999 00:35:44 -0500 (EST)
+* From: Denes Molnar
+* To: fortran@gnu.org
+* Subject: f771 gets fatal signal 6
+* Content-Type: TEXT/PLAIN; charset=US-ASCII
+* X-UIDL: 8d81e9cbdcc96209c6e9b298d966ba7f
+*
+* Hi,
+*
+*
+* Comiling object from the source code below WORKS FINE with
+* 'g77 -o hwuci2 -c hwuci2.F'
+* but FAILS with fatal signal 6
+* 'g77 -o hwuci2 -O -c hwuci2.F'
+*
+* Any explanations?
+*
+* I am running GNU Fortran 0.5.23 with GCC 2.8.1 (glibc1).
+*
+*
+* Denes Molnar
+*
+* %%%%%%%%%%%%%%%%%%%%%%%%%
+* %the source:
+* %%%%%%%%%%%%%%%%%%%%%%%%%
+*
+CDECK ID>, HWUCI2.
+*CMZ :- -23/08/94 13.22.29 by Mike Seymour
+*-- Author : Ulrich Baur & Nigel Glover, adapted by Ian Knowles
+C-----------------------------------------------------------------------
+ FUNCTION HWUCI2(A,B,Y0)
+C-----------------------------------------------------------------------
+C Integral LOG(A-EPSI-BY(1-Y))/(Y-Y0)
+C-----------------------------------------------------------------------
+ IMPLICIT NONE
+ complex(kind=8) HWUCI2,HWULI2,EPSI,Y1,Y2,Z1,Z2,Z3,Z4
+ DOUBLE PRECISION A,B,Y0,ZERO,ONE,FOUR,HALF
+ EXTERNAL HWULI2
+ COMMON/SMALL/EPSI
+ PARAMETER (ZERO=0.D0, ONE =1.D0, FOUR= 4.D0, HALF=0.5D0)
+ IF(B.EQ.ZERO)THEN
+ HWUCI2=CMPLX(ZERO,ZERO)
+ ELSE
+ Y1=HALF*(ONE+SQRT(ONE-FOUR*(A+EPSI)/B))
+ Y2=ONE-Y1
+ Z1=Y0/(Y0-Y1)
+ Z2=(Y0-ONE)/(Y0-Y1)
+ Z3=Y0/(Y0-Y2)
+ Z4=(Y0-ONE)/(Y0-Y2)
+ HWUCI2=HWULI2(Z1)-HWULI2(Z2)+HWULI2(Z3)-HWULI2(Z4)
+ ENDIF
+ RETURN
+ END
+*
+* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Index: Fortran/gfortran/regression/g77/19990313-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990313-0.f
@@ -0,0 +1,34 @@
+c { dg-do run }
+* To: craig@jcb-sc.com
+* Subject: Re: G77 and KIND=2
+* Content-Type: text/plain; charset=us-ascii
+* From: Dave Love
+* Date: 03 Mar 1999 18:20:11 +0000
+* In-Reply-To: craig@jcb-sc.com's message of "1 Mar 1999 21:04:38 -0000"
+* User-Agent: Gnus/5.07007 (Pterodactyl Gnus v0.70) Emacs/20.3
+* X-UIDL: d442bafe961c2a6ec6904f492e05d7b0
+*
+* ISTM that there is a real problem printing integer(kind=8) (on x86):
+*
+* $ cat x.f
+*[modified for test suite]
+ integer(kind=8) foo, bar
+ data r/4e10/
+ foo = 4e10
+ bar = r
+ if (foo .ne. bar) STOP 1
+ end
+* $ g77 x.f && ./a.out
+* 1345294336
+* 123
+* $ f2c x.f && g77 x.c && ./a.out
+* x.f:
+* MAIN:
+* 40000000000
+* 123
+* $
+*
+* Gdb shows the upper half of the buffer passed to do_lio is zeroed in
+* the g77 case.
+*
+* I've forgotten how the code generation happens.
Index: Fortran/gfortran/regression/g77/19990313-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990313-1.f
@@ -0,0 +1,8 @@
+c { dg-do run }
+ integer(kind=8) foo, bar
+ double precision r
+ data r/4d10/
+ foo = 4d10
+ bar = r
+ if (foo .ne. bar) STOP 1
+ end
Index: Fortran/gfortran/regression/g77/19990313-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990313-2.f
@@ -0,0 +1,8 @@
+c { dg-do run }
+ integer(kind=8) foo, bar
+ complex c
+ data c/(4e10,0)/
+ foo = 4e10
+ bar = c
+ if (foo .ne. bar) STOP 1
+ end
Index: Fortran/gfortran/regression/g77/19990313-3.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990313-3.f
@@ -0,0 +1,8 @@
+c { dg-do run }
+ integer(kind=8) foo, bar
+ complex(kind=8) c
+ data c/(4d10,0)/
+ foo = 4d10
+ bar = c
+ if (foo .ne. bar) STOP 1
+ end
Index: Fortran/gfortran/regression/g77/19990419-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990419-0.f
@@ -0,0 +1,8 @@
+c { dg-do compile }
+* Test case Toon submitted, cut down to expose the one bug.
+* Belongs in compile/.
+ SUBROUTINE INIERS1
+ IMPLICIT LOGICAL(L)
+ COMMON/COMIOD/ NHIERS1, LERS1
+ inquire(nhiers1, exist=lers1)
+ END
Index: Fortran/gfortran/regression/g77/19990419-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990419-1.f
@@ -0,0 +1,22 @@
+c { dg-do run }
+* Test DO WHILE, to make sure it fully reevaluates its expression.
+* Belongs in execute/.
+ common /x/ ival
+ j = 0
+ do while (i() .eq. 1)
+ j = j + 1
+ if (j .gt. 5) STOP 1
+ end do
+ if (j .ne. 4) STOP 2
+ if (ival .ne. 5) STOP 3
+ end
+ function i()
+ common /x/ ival
+ ival = ival + 1
+ i = 10
+ if (ival .lt. 5) i = 1
+ end
+ block data
+ common /x/ ival
+ data ival/0/
+ end
Index: Fortran/gfortran/regression/g77/19990502-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990502-0.f
@@ -0,0 +1,67 @@
+c { dg-do compile }
+* Mailing-List: contact egcs-bugs-help@egcs.cygnus.com; run by ezmlm
+* Precedence: bulk
+* Sender: owner-egcs-bugs@egcs.cygnus.com
+* From: Norbert Conrad
+* Subject: egcs g77 19990524pre Internal compiler error in `print_operand'
+* To: egcs-bugs@egcs.cygnus.com
+* Date: Mon, 31 May 1999 11:46:52 +0200 (CET)
+* Content-Type: text/plain; charset=US-ASCII
+* X-UIDL: 9a00095a5fe4d774b7223de071157374
+*
+* Hi,
+*
+* I ./configure --prefix=/opt and bootstrapped egcs g77 snapshot 19990524
+* on an i686-pc-linux-gnu. The program below gives an internal compiler error.
+*
+*
+* Script started on Mon May 31 11:30:01 1999
+* lx{g010}:/tmp>/opt/bin/g77 -v -O3 -malign-double -c e3.f
+* g77 version gcc-2.95 19990524 (prerelease) (from FSF-g77 version 0.5.24-19990515)
+* Reading specs from /opt/lib/gcc-lib/i686-pc-linux-gnu/gcc-2.95/specs
+* gcc version gcc-2.95 19990524 (prerelease)
+* /opt/lib/gcc-lib/i686-pc-linux-gnu/gcc-2.95/f771 e3.f -quiet -dumpbase e3.f -malign-double -O3 -version -fversion -o /tmp/ccQgeaaa.s
+* GNU F77 version gcc-2.95 19990524 (prerelease) (i686-pc-linux-gnu) compiled by GNU C version gcc-2.95 19990524 (prerelease).
+* GNU Fortran Front End version 0.5.24-19990515
+* e3.f:25: Internal compiler error in `print_operand', at ./config/i386/i386.c:3405
+* Please submit a full bug report to `egcs-bugs@egcs.cygnus.com'.
+* See for details.
+* lx{g010}:/tmp>cat e3.f
+ SUBROUTINE DLASQ2( QQ, EE, TOL2, SMALL2 )
+ DOUBLE PRECISION SMALL2, TOL2
+ DOUBLE PRECISION EE( * ), QQ( * )
+ INTEGER ICONV, N, OFF
+ DOUBLE PRECISION QEMAX, XINF
+ EXTERNAL DLASQ3
+ INTRINSIC MAX, SQRT
+ XINF = 0.0D0
+ ICONV = 0
+ IF( EE( N ).LE.MAX( QQ( N ), XINF, SMALL2 )*TOL2 ) THEN
+ END IF
+ IF( EE( N-2 ).LE.MAX( XINF, SMALL2,
+ $ ( QQ( N ) / ( QQ( N )+EE( N-1 ) ) )* QQ( N-1 ))*TOL2 ) THEN
+ QEMAX = MAX( QQ( N ), QQ( N-1 ), EE( N-1 ) )
+ END IF
+ IF( N.EQ.0 ) THEN
+ IF( OFF.EQ.0 ) THEN
+ RETURN
+ ELSE
+ XINF =0.0D0
+ END IF
+ ELSE IF( N.EQ.2 ) THEN
+ END IF
+ CALL DLASQ3(ICONV)
+ END
+* lx{g010}:/tmp>exit
+*
+* Script done on Mon May 31 11:30:23 1999
+*
+* Best regards,
+*
+* Norbert.
+* --
+* Norbert Conrad phone: ++49 641 9913021
+* Hochschulrechenzentrum email: conrad@hrz.uni-giessen.de
+* Heinrich-Buff-Ring 44
+* 35392 Giessen
+* Germany
Index: Fortran/gfortran/regression/g77/19990502-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990502-1.f
@@ -0,0 +1,7 @@
+c { dg-do compile }
+ SUBROUTINE G(IGAMS,IWRK,NADC,NCellsInY)
+ INTEGER(kind=2) IGAMS(2,NADC)
+ in = 1
+ do while (in.le.nadc.and.IGAMS(2,in).le.in)
+ enddo
+ END
Index: Fortran/gfortran/regression/g77/19990525-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990525-0.f
@@ -0,0 +1,53 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+c
+* Mailing-List: contact egcs-bugs-help@egcs.cygnus.com; run by ezmlm
+* Precedence: bulk
+* Sender: owner-egcs-bugs@egcs.cygnus.com
+* From: "Bjorn R. Bjornsson"
+* Subject: g77 char expr. as arg to subroutine bug
+* To: egcs-bugs@egcs.cygnus.com
+* Date: Tue, 25 May 1999 14:45:56 +0000 (GMT)
+* Content-Type: text/plain; charset=US-ASCII
+* X-UIDL: 06000c94269ed6dfe826493e52a818b9
+*
+* The following bug is in all snapshots starting
+* from April 18. I have only tested this on Alpha linux,
+* and with FFECOM_FASTER_ARRAY_REFS set to 1.
+*
+* Run the following through g77:
+*
+ subroutine a
+ character*2 string1
+ character*2 string2
+ character*4 string3
+ string1 = 's1'
+ string2 = 's2'
+c
+c the next 2 lines are ok.
+ string3 = (string1 // string2)
+ call b(string1//string2)
+c
+c this line gives gcc/f/com.c:10660: failed assertion `hook'
+ call b((string1//string2))
+ end
+*
+* the output from:
+*
+* /usr/local/egcs-19990418/bin/g77 --verbose -c D.f
+*
+* is:
+*
+* on egcs-2.93.19 19990418 (gcc2 ss-980929 experimental) (from FSF-g77 version 0.5.24-19990418)
+* Reading specs from /usr/local/egcs-19990418/lib/gcc-lib/alphaev56-unknown-linux-gnu/egcs-2.93.19/specs
+* gcc version egcs-2.93.19 19990418 (gcc2 ss-980929 experimental)
+* /usr/local/egcs-19990418/lib/gcc-lib/alphaev56-unknown-linux-gnu/egcs-2.93.19/f771 D.f -quiet -dumpbase D.f -version -fversion -o /tmp/ccNpaaaa.s
+* GNU F77 version egcs-2.93.19 19990418 (gcc2 ss-980929 experimental) (alphaev56-unknown-linux-gnu) compiled by GNU C version egcs-2.93.19 19990418 (gcc2 ss-980929 experimental).
+* GNU Fortran Front End version 0.5.24-19990418
+* ../../../egcs-19990418/gcc/f/com.c:10351: failed assertion `hook'
+* g77: Internal compiler error: program f771 got fatal signal 6
+*
+* Yours,
+*
+* Bjorn R. Bjornsson
+* brb@halo.hi.is
Index: Fortran/gfortran/regression/g77/19990826-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990826-0.f
@@ -0,0 +1,20 @@
+c { dg-do run }
+* From: niles@fan745.gsfc.nasa.gov
+* To: fortran@gnu.org
+* Cc: niles@fan745.gsfc.nasa.gov
+* Subject: problem with DNINT() on Linux/Alpha.
+* Date: Sun, 06 Jun 1999 16:39:35 -0400
+* X-UIDL: 6aa9208d7bda8b6182a095dfd37016b7
+
+ IF (DNINT(0.0D0) .NE. 0.) STOP 1
+ STOP
+ END
+
+* Result on Linux/i386: " 0." (and every other computer!)
+* Result on Linux/alpha: " 3.6028797E+16"
+
+* It seems to work fine if I change it to the generic NINT(). Probably
+* a name pollution problem in the new C library, but it seems bad. no?
+
+* Thanks,
+* Rick Niles.
Index: Fortran/gfortran/regression/g77/19990826-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990826-1.f
@@ -0,0 +1,287 @@
+c { dg-do compile }
+* Date: Tue, 24 Aug 1999 12:25:41 +1200 (NZST)
+* From: Jonathan Ravens
+* To: gcc-bugs@gcc.gnu.org
+* Subject: g77 bug report
+* X-UIDL: a0bf5ecc21487cde48d9104983ab04d6
+
+! This fortran source will not compile - if the penultimate elseif block is 0
+! included then the message appears :
+!
+! /usr/src/egcs//gcc-2.95.1/gcc/f/stw.c:308: failed assertion `b->uses_ > 0'
+! g77: Internal compiler error: program f771 got fatal signal 6
+!
+! The command was : g77 -c
+!
+! The OS is Red Hat 6, and the output from uname -a is
+! Linux grfw1452.gns.cri.nz 2.2.5-15 #1 Mon Apr 19 23:00:46 EDT 1999 i686 unknown
+!
+! The configure script I used was
+! /usr/src/egcs/gcc/gcc-2.95.1/configure --enable-languages=f77 i585-unknown-linux
+!
+! I was installing 2.95 because under EGCS 2.1.1 none of my code was working
+! with optimisation turned on, and there were still bugs with no optimisation
+! (all of which code works fine under g77 0.5.21 and Sun/IBM/Dec/HP fortrans).
+!
+! The version of g77 is :
+!
+!g77 version 2.95.1 19990816 (release) (from FSF-g77 version 0.5.25 19990816 (release))
+
+ program main
+ if (i.eq.1) then
+ call abc(1)
+ else if (i.eq. 1) then
+ call abc( 1)
+ else if (i.eq. 2) then
+ call abc( 2)
+ else if (i.eq. 3) then
+ call abc( 3)
+ else if (i.eq. 4) then
+ call abc( 4)
+ else if (i.eq. 5) then
+ call abc( 5)
+ else if (i.eq. 6) then
+ call abc( 6)
+ else if (i.eq. 7) then
+ call abc( 7)
+ else if (i.eq. 8) then
+ call abc( 8)
+ else if (i.eq. 9) then
+ call abc( 9)
+ else if (i.eq. 10) then
+ call abc( 10)
+ else if (i.eq. 11) then
+ call abc( 11)
+ else if (i.eq. 12) then
+ call abc( 12)
+ else if (i.eq. 13) then
+ call abc( 13)
+ else if (i.eq. 14) then
+ call abc( 14)
+ else if (i.eq. 15) then
+ call abc( 15)
+ else if (i.eq. 16) then
+ call abc( 16)
+ else if (i.eq. 17) then
+ call abc( 17)
+ else if (i.eq. 18) then
+ call abc( 18)
+ else if (i.eq. 19) then
+ call abc( 19)
+ else if (i.eq. 20) then
+ call abc( 20)
+ else if (i.eq. 21) then
+ call abc( 21)
+ else if (i.eq. 22) then
+ call abc( 22)
+ else if (i.eq. 23) then
+ call abc( 23)
+ else if (i.eq. 24) then
+ call abc( 24)
+ else if (i.eq. 25) then
+ call abc( 25)
+ else if (i.eq. 26) then
+ call abc( 26)
+ else if (i.eq. 27) then
+ call abc( 27)
+ else if (i.eq. 28) then
+ call abc( 28)
+ else if (i.eq. 29) then
+ call abc( 29)
+ else if (i.eq. 30) then
+ call abc( 30)
+ else if (i.eq. 31) then
+ call abc( 31)
+ else if (i.eq. 32) then
+ call abc( 32)
+ else if (i.eq. 33) then
+ call abc( 33)
+ else if (i.eq. 34) then
+ call abc( 34)
+ else if (i.eq. 35) then
+ call abc( 35)
+ else if (i.eq. 36) then
+ call abc( 36)
+ else if (i.eq. 37) then
+ call abc( 37)
+ else if (i.eq. 38) then
+ call abc( 38)
+ else if (i.eq. 39) then
+ call abc( 39)
+ else if (i.eq. 40) then
+ call abc( 40)
+ else if (i.eq. 41) then
+ call abc( 41)
+ else if (i.eq. 42) then
+ call abc( 42)
+ else if (i.eq. 43) then
+ call abc( 43)
+ else if (i.eq. 44) then
+ call abc( 44)
+ else if (i.eq. 45) then
+ call abc( 45)
+ else if (i.eq. 46) then
+ call abc( 46)
+ else if (i.eq. 47) then
+ call abc( 47)
+ else if (i.eq. 48) then
+ call abc( 48)
+ else if (i.eq. 49) then
+ call abc( 49)
+ else if (i.eq. 50) then
+ call abc( 50)
+ else if (i.eq. 51) then
+ call abc( 51)
+ else if (i.eq. 52) then
+ call abc( 52)
+ else if (i.eq. 53) then
+ call abc( 53)
+ else if (i.eq. 54) then
+ call abc( 54)
+ else if (i.eq. 55) then
+ call abc( 55)
+ else if (i.eq. 56) then
+ call abc( 56)
+ else if (i.eq. 57) then
+ call abc( 57)
+ else if (i.eq. 58) then
+ call abc( 58)
+ else if (i.eq. 59) then
+ call abc( 59)
+ else if (i.eq. 60) then
+ call abc( 60)
+ else if (i.eq. 61) then
+ call abc( 61)
+ else if (i.eq. 62) then
+ call abc( 62)
+ else if (i.eq. 63) then
+ call abc( 63)
+ else if (i.eq. 64) then
+ call abc( 64)
+ else if (i.eq. 65) then
+ call abc( 65)
+ else if (i.eq. 66) then
+ call abc( 66)
+ else if (i.eq. 67) then
+ call abc( 67)
+ else if (i.eq. 68) then
+ call abc( 68)
+ else if (i.eq. 69) then
+ call abc( 69)
+ else if (i.eq. 70) then
+ call abc( 70)
+ else if (i.eq. 71) then
+ call abc( 71)
+ else if (i.eq. 72) then
+ call abc( 72)
+ else if (i.eq. 73) then
+ call abc( 73)
+ else if (i.eq. 74) then
+ call abc( 74)
+ else if (i.eq. 75) then
+ call abc( 75)
+ else if (i.eq. 76) then
+ call abc( 76)
+ else if (i.eq. 77) then
+ call abc( 77)
+ else if (i.eq. 78) then
+ call abc( 78)
+ else if (i.eq. 79) then
+ call abc( 79)
+ else if (i.eq. 80) then
+ call abc( 80)
+ else if (i.eq. 81) then
+ call abc( 81)
+ else if (i.eq. 82) then
+ call abc( 82)
+ else if (i.eq. 83) then
+ call abc( 83)
+ else if (i.eq. 84) then
+ call abc( 84)
+ else if (i.eq. 85) then
+ call abc( 85)
+ else if (i.eq. 86) then
+ call abc( 86)
+ else if (i.eq. 87) then
+ call abc( 87)
+ else if (i.eq. 88) then
+ call abc( 88)
+ else if (i.eq. 89) then
+ call abc( 89)
+ else if (i.eq. 90) then
+ call abc( 90)
+ else if (i.eq. 91) then
+ call abc( 91)
+ else if (i.eq. 92) then
+ call abc( 92)
+ else if (i.eq. 93) then
+ call abc( 93)
+ else if (i.eq. 94) then
+ call abc( 94)
+ else if (i.eq. 95) then
+ call abc( 95)
+ else if (i.eq. 96) then
+ call abc( 96)
+ else if (i.eq. 97) then
+ call abc( 97)
+ else if (i.eq. 98) then
+ call abc( 98)
+ else if (i.eq. 99) then
+ call abc( 99)
+ else if (i.eq. 100) then
+ call abc( 100)
+ else if (i.eq. 101) then
+ call abc( 101)
+ else if (i.eq. 102) then
+ call abc( 102)
+ else if (i.eq. 103) then
+ call abc( 103)
+ else if (i.eq. 104) then
+ call abc( 104)
+ else if (i.eq. 105) then
+ call abc( 105)
+ else if (i.eq. 106) then
+ call abc( 106)
+ else if (i.eq. 107) then
+ call abc( 107)
+ else if (i.eq. 108) then
+ call abc( 108)
+ else if (i.eq. 109) then
+ call abc( 109)
+ else if (i.eq. 110) then
+ call abc( 110)
+ else if (i.eq. 111) then
+ call abc( 111)
+ else if (i.eq. 112) then
+ call abc( 112)
+ else if (i.eq. 113) then
+ call abc( 113)
+ else if (i.eq. 114) then
+ call abc( 114)
+ else if (i.eq. 115) then
+ call abc( 115)
+ else if (i.eq. 116) then
+ call abc( 116)
+ else if (i.eq. 117) then
+ call abc( 117)
+ else if (i.eq. 118) then
+ call abc( 118)
+ else if (i.eq. 119) then
+ call abc( 119)
+ else if (i.eq. 120) then
+ call abc( 120)
+ else if (i.eq. 121) then
+ call abc( 121)
+ else if (i.eq. 122) then
+ call abc( 122)
+ else if (i.eq. 123) then
+ call abc( 123)
+ else if (i.eq. 124) then
+ call abc( 124)
+ else if (i.eq. 125) then !< Miscompiles if present
+ call abc( 125) !<
+
+c else if (i.eq. 126) then
+c call abc( 126)
+ endif
+ end
Index: Fortran/gfortran/regression/g77/19990826-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990826-2.f
@@ -0,0 +1,36 @@
+c { dg-do run }
+c { dg-options "-std=legacy" }
+c
+* From: "Billinghurst, David (RTD)"
+* Subject: RE: single precision complex bug in g77 - was Testing g77 with LA
+* PACK 3.0
+* Date: Thu, 8 Jul 1999 00:55:11 +0100
+* X-UIDL: b00d9d8081a36fef561b827d255dd4a5
+
+* Here is a slightly simpler and neater test case
+
+ program labug3
+ implicit none
+
+* This program gives the wrong answer on mips-sgi-irix6.5
+* when compiled with g77 from egcs-19990629 (gcc 2.95 prerelease)
+* Get a = 0.0 when it should be 1.0
+*
+* Works with: -femulate-complex
+* egcs-1.1.2
+*
+* Originally derived from LAPACK 3.0 test suite.
+*
+* David Billinghurst, (David.Billinghurst@riotinto.com.au)
+* 8 July 1999
+*
+ complex one, z
+ real a, f1
+ f1(z) = real(z)
+ one = (1.,0.)
+ a = f1(one)
+ if ( abs(a-1.0) .gt. 1.0e-5 ) then
+ write(6,*) 'A should be 1.0 but it is',a
+ STOP 1
+ end if
+ end
Index: Fortran/gfortran/regression/g77/19990826-3.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990826-3.f
@@ -0,0 +1,321 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+* Date: Thu, 19 Aug 1999 10:02:32 +0200
+* From: Frederic Devernay
+* Organization: ISTAR
+* X-Accept-Language: French, fr, en
+* To: gcc-bugs@gcc.gnu.org
+* Subject: g77 2.95 bug (Internal compiler error in `final_scan_insn')
+* X-UIDL: 08443f5c374ffa382a05573281482f4f
+
+* Here's a bug that happens only when I compile with -O (disappears with
+* -O2)
+
+* > g77 -v --save-temps -O -c pcapop.f
+* g77 version 2.95 19990728 (release) (from FSF-g77 version 0.5.25
+* 19990728 (release))
+* Reading specs from
+* /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95/specs
+* gcc version 2.95 19990728 (release)
+* /usr/local/lib/gcc-lib/sparc-sun-solaris2.6/2.95/f771 pcapop.f -quiet
+* -dumpbase pcapop.f -O -version -fversion -o pcapop.s
+* GNU F77 version 2.95 19990728 (release) (sparc-sun-solaris2.6) compiled
+* by GNU C version 2.95 19990728 (release).
+* GNU Fortran Front End version 0.5.25 19990728 (release)
+* pcapop.f: In subroutine `pcapop':
+* pcapop.f:291: Internal compiler error in `final_scan_insn', at
+* final.c:2920
+* Please submit a full bug report.
+* See for instructions.
+
+C* PCAPOP
+ SUBROUTINE PCAPOP(M1,M2,L1,L2,NMEM,N1,N2,IB,IBB,K3,TF,TS,TC,TTO)
+ DIMENSION NVA(6),C(6),I(6)
+C
+C CALCUL DES PARAMETRES OPTIMAUX N1 N2 IB IBB
+C
+ TACC=.035
+ TTRANS=.000004
+ RAD=.000001
+ RMI=.000001
+ RMU=.0000015
+ RDI=.000003
+ RTE=.000003
+ REQ=.000005
+ VY1=3*RTE+RDI+8*REQ+3*(RAD+RMI+RMU)
+ VY2=REQ+2*RAD
+ AR2=M2*(2*(REQ+RMI)+3*RMU+M1*(2*RAD+REQ))
+C VARIATION DE L1,L2,
+C
+ TTOTOP=1.E+10
+ N1CO=0
+ N2CO=0
+ IBCO=0
+ IBBCO=0
+ K3CO=0
+ TESOP=0.
+ TCOP=0.
+ TFOP=0.
+ INUN=7
+ INDE=7
+ IF(M1.LT.128)INUN=6
+ IF(M1.LT.64)INUN=5
+ IF(M1.LT.32)INUN=4
+ IF(M2.LT.128)INDE=6
+ IF(M2.LT.64)INDE=5
+ IF(M2.LT.32)INDE=4
+ DO 3 NUN =3,INUN
+ DO 3 NDE=3,INDE
+ N10=2**NUN
+ N20=2**NDE
+ NDIF=(N10-N20)
+ NDIF=IABS(NDIF)
+C POUR AVOIR CES RESULTATS FAIRE TOURNER LE PROGRAMME VEFFT1
+ TCFFTU=0.
+ IF(N10.EQ.128.AND.N20.EQ.128)TCFFTU=3.35
+ IF(N10.EQ.64.AND.N20.EQ.64)TCFFTU=.70
+ IF(N10.EQ.32.AND.N20.EQ.32)TCFFTU=.138
+ IF(N10.EQ.16.AND.N20.EQ.16)TCFFTU=.0332
+ IF(N10.EQ.8.AND.N20.EQ.8)TCFFTU=.00688
+ IF(NDIF.EQ.64)TCFFTU=1.566
+ IF(NDIF.EQ.96)TCFFTU=.709
+ IF(NDIF.EQ.112)TCFFTU=.349
+ IF(NDIF.EQ.120)TCFFTU=.160
+ IF(NDIF.EQ.32)TCFFTU=.315
+ IF(NDIF.EQ.48)TCFFTU=.154
+ IF(NDIF.EQ.56)TCFFTU=.07
+ IF(NDIF.EQ.16)TCFFTU=.067
+ IF(NDIF.EQ.24)TCFFTU=.030
+ IF(NDIF.EQ.8)TCFFTU=.016
+ N30=N10-L1+1
+ N40=N20-L2+1
+ WW=VY1+N30*VY2
+ NDOU=2*N10*N20
+ IF((N10.LT.L1).OR.(N20.LT.L2)) GOTO 3
+ NB=NMEM-NDOU-N20*(L1-1)
+ NVC=2*N10*(N20-1)+M1
+ IF(NB.LT.(NVC)) GOTO 3
+ CALL VALENT(M1,N30,K1)
+ CALL VALENT(M2,N40,K2)
+ IS=K1/2
+ IF((2*IS).NE.K1)K1=K1+1
+ TFF=TCFFTU*K1*K2
+ CALL VALENT(M2,N40,JOFI)
+ IF(NB.GE.(K1*N20*N30+2*N20*(L1-1))) GOTO 4
+ TIOOP=1.E+10
+ IC=1
+18 IB1=2*IC
+ MAX=(NB-2*N20*(L1-1))/(N20*N30)
+ IN=MAX/2
+ IF(MAX.NE.2*IN) MAX=MAX-1
+ K3=K1/IB1
+ IBB1=K1-K3*IB1
+ IOFI=M1/(IB1*N30)
+ IRZ=0
+ IF(IOFI*IB1*N30.EQ.M1) GOTO1234
+ IRZ=1
+ IOFI=IOFI+1
+ IF(IBB1.EQ.0) GOTO 1234
+ IF(M1.EQ.((IOFI-1)*IB1*N30+IBB1*N30)) GOTO 1233
+ IRZ=2
+ GOTO 1234
+1233 IRZ=3
+1234 IBX1=IBB1
+ IF(IBX1.EQ.0)IBX1=IB1
+ AR1=M2*(2*(RAD+RMI+RMU+REQ)+(M1-(IOFI-1)*IB1*N30)*2*(REQ+RAD))
+ %+M2*(3*(REQ+RMU+RAD)+4*RMI+(M1-(IOFI-1)*IB1*N30)*(2*RAD+REQ)
+ %+(IOFI-1)*IB1*N30*(2*RMI+REQ+RAD))
+ AR5=(JOFI-1)*(N20-L2)*(M1-(IOFI-1)*IB1*N30)*(2*(RAD+RMU)+REQ)
+ %*IOFI+(M2-(JOFI-1)*N40+L2-2)*(M1-(IOFI-1)*IB1*N30)*(2*(RAD+RMU
+ %)+REQ)*IOFI
+ WQ=((IOFI-1)*IB1+IBX1)*JOFI*WW
+ AT1=N20*WQ
+ AT2=N40*WQ
+ QW=JOFI*(VY1+VY2*IB1*N30)
+ AT3=IOFI*N40*QW
+ AT4=(IOFI-1)*N40*QW
+ AT5=JOFI*((IOFI-1)*N40*(IB1/IBX1)*(VY1+IBX1*N30*VY2)
+ %+N40*((IB1/IBX1)*(IOFI-1)+1)*(VY1+IBX1*N30*VY2))
+ AT6=JOFI*((IOFI-1)*N40*(IB1/2)*(VY1+2*N30*VY2)+N40*(
+ %IB1*(IOFI-1)/2+IBX1/2)*(VY1+2*N30*VY2))
+ T1=JOFI*N20*(L1-1)*REQ
+ T2=M1*(L2-1)*REQ
+ T3=JOFI*N20*IBX1*N30*(RAD+REQ)
+ T4=JOFI*((IOFI-1)*IB1*N30*N20*(2*RMI+REQ)+IBX1*N30*N20*(2*RMI+R
+ %EQ))
+ T5=JOFI*((IOFI-1)*IB1/2+IBX1/2)*N20*N30*(2*RAD+REQ)
+ T6=2*JOFI*(((IOFI-1)*IB1+IBX1)*N20)*((5*(RMI+RMU)+4*RAD
+ %)+(L1-1)*(2*RAD+REQ)+N30*(2*RAD+REQ))
+ T7=JOFI*2*((IOFI-1)*IB1+IBX1)*(L1-1)*(2*RAD+REQ)
+ T8=JOFI*N10*N20*((IOFI-1)*IB1/2+IBX1/2)*(3*REQ+9*RAD+4*RMU+RMI)
+ T9=N10*N20*JOFI*((IOFI-1)*IB1/2+IBX1/2)*(REQ+RMI)+M1*M2*(REQ+R
+ %DI+2*RAD)
+ T10=JOFI*((IOFI-1)*IB1/2+IBX1/2)*2*(3*RMU+2*(RMI+RAD)+N40*(3*RMI
+ %+4*RMU+3*(RAD+REQ)+N30*(2*RAD+REQ)))
+ POI=JOFI
+ IF(POI.LE.2)POI=2
+ TNRAN=(N40+(POI-2)*N20+(M2-(JOFI-1)*N40+L2-1))*(RMI+RMU+RAD
+ %+REQ+N30*(2*RAD+2*REQ)*(IB1*(IOFI-1)+IBX1))
+ IF(TNRAN.LT.0.)TNRAN=0.
+ TCPU=T1+T2+T3+T4+T5+T6+T7+T8+T9+T10+TNRAN
+ NVA(1)=N40
+ NVA(2)=N40
+ NVA(3)=N20
+ NVA(4)=N20
+ NVA(5)=M2-(JOFI-1)*N40
+ NVA(6)=NVA(5)
+ C(1)=FLOAT(IB1*N30)/FLOAT(M1)
+ C(2)=FLOAT(M1-(IOFI-1)*IB1*N30)/FLOAT(M1)
+ C(3)=C(1)
+ C(4)=C(2)
+ C(5)=C(1)
+ C(6)=C(2)
+ K=1
+ P1=FLOAT(NB)/FLOAT(M1)
+10 IP1=P1
+ I(K)=1
+ IF(IP1.GE.NVA(K)) GOTO 7
+ P2=P1
+ IP2=P2
+8 P2=P2-FLOAT(IP2)*C(K)
+ IP2=P2
+ IF(IP2.EQ.0) GOTO 3
+ IP1=IP1+IP2
+ I(K)=I(K)+1
+ IF(IP1.GE.NVA(K))GOTO 7
+ GOTO 8
+7 IF(K.EQ.6) GOTO 11
+ K=K+1
+ GOTO 10
+11 IP1=0
+ IP2=0
+ IP3=0
+ POFI=JOFI
+ IF(POFI.LE.2)POFI=2
+ TIOL=(I(2)+(IOFI-1)*I(1)+(POFI-2)*(IOFI-1)*I(3)+(POFI-
+ %2)*I(4)+(IOFI-1)*I(5)+I(6))*TACC+(IOFI*M1*N40+(POFI-2)*IOFI*
+ %M1*N20+(M2-(JOFI-1)*N40+L2-1)*M1*IOFI)*TTRANS
+ IF(IBB1.EQ.0) GOTO 33
+ IF(IB1.EQ.IBB1) GOTO 33
+ IF(IBB1.EQ.2)GOTO 34
+ IP3=1
+ INL=NMEM/((IOFI-1)*IB1*N30+IBB1*N30)
+55 IF(INL.GT.N40)INL=N40
+ GOTO 35
+33 IF(IB1.GT.2) GOTO 36
+ IF((M1-(IOFI-1)*IB1*N30).GE.N30) GOTO 36
+34 IP1=1
+ INL=NMEM/(2*M1-(IOFI-1)*IB1*N30)
+ GOTO 55
+36 IP2=1
+ INL=NMEM/(IOFI*IB1*N30)
+ IF(INL.GT.N40)INL=N40
+35 CALL VALENT(N40,INL,KN1)
+ CALL VALENT(M2-(JOFI-1)*N40,INL,KN2)
+ CALL VALENT(INL*IBB1,IB1,KN3)
+ CALL VALENT((N40-(KN1-1)*INL)*IBB1,IB1,KN4)
+ IF((IP1+IP2+IP3).NE.1) CALL ERMESF(14)
+ TIO1=0.
+ IF(IP3.EQ.1)TIO1=N30*M2*TTRANS*(IB1*(IOFI-1)+IBB1)
+ IF(IP1.EQ.1)TIO1=M1*M2*TTRANS
+ IF(IP2.EQ.1) TIO1=(IB1*N30*M2*IOFI*TTRANS)
+ TTIO=2.*TIO1+(KN1*IOFI*(JOFI-1)+KN2*IOFI+(KN1-1)*(
+ %JOFI-1)+IOFI*(JOFI-1)+KN2-1.+IOFI+(KN1*(JOFI-1)+KN2))*TACC
+ %+M1*M2*TTRANS+TIOL
+ IF((IP1.EQ.1).AND.(IRZ.EQ.0))TCPU=TCPU+AT1+AT2+AT3
+ IF((IP1.EQ.1).AND.(IRZ.NE.0))TCPU=TCPU+AT1+AT2+AT4+AR1
+ IF((IP2.EQ.1).AND.(IRZ.EQ.0))TCPU=TCPU+AT1+AT2+AT3
+ IF((IP2.EQ.1).AND.(IRZ.NE.0))TCPU=TCPU+AT1+AT2+AT3+AR2
+ IFOIS=IB1/IBX1
+ IF((IP3.EQ.1).AND.(IFOIS*IBX1.EQ.IB1))TCPU=TCPU+AT1+AT2+AT5+AR2
+ IF((IP3.EQ.1).AND.(IFOIS*IBX1.NE.IB1))TCPU=TCPU+AT1+AT2+AT6+AR2
+ IF((IP1.EQ.1).AND.(IRZ.EQ.1))TCPU=TCPU+AR5
+ IF((IP1.EQ.1).AND.(IRZ.EQ.2))TCPU=TCPU+AR5
+ TTIOG=TTIO+TCPU
+ IF(TTIOG.LE.0.) GOTO 99
+ IF(TTIOG.GE.TIOOP) GOTO 99
+ IBOP=IB1
+ IBBOP=IBB1
+ K3OP=K3
+ TIOOP=TTIOG
+ TIOOP1=TTIO
+ TIOOP2=TCPU
+99 IF(IB1.GE.MAX)GOTO17
+ IC=IC+1
+ GOTO 18
+4 T1=JOFI*N20*(L1-1)*REQ
+ T2=M1*(L2-1)*REQ
+ T3=JOFI*N20*N30*(RAD+REQ)*K1
+ T4=JOFI*(K1*N30*N20*(2*RMI+REQ))
+ T5=JOFI*N20*N30*(2*RAD+REQ)*K1/2
+ T6=2*JOFI*(K1*N20)*((5*RMI+RMU)+4*RAD+(L1-1)*(2*RAD+REQ)+N30*2*
+ %RAD+REQ)
+ T7=JOFI*2*K1*(L1-1)*(2*RAD+REQ)
+ T9=JOFI*N10*N20*K1*(REQ+RMI)/2+M1*M2*(REQ+RDI+2*RAD)
+ T8=JOFI*N10*N20*K1*(3*REQ+9*RAD+4*RMU+RMI)/2
+ T10=JOFI*K1*(3*RMU+2*(RMI+RAD)+N40*(3*RMI
+ %+4*RMU+3*(RAD+REQ)+N30*(2*RAD+REQ)))
+ PIO=JOFI
+ IF(PIO.LE.2)PIO=2
+ TNR=(N40+(PIO-2)*N20+(M2-(JOFI-1)*N40+L2-1))*(RMU+RMI+RAD+REQ+
+ %N30*(2*RAD+2*REQ)*K1)
+ IF(TNR.LE.0.)TNR=0.
+ BT1=JOFI*N20*WW*K1
+ BT2=JOFI*N40*WW*K1
+ BT3=JOFI*N40*(VY1+K1*N30*VY2)
+ BR1=M2*(2*(RAD+RMI+RMU+REQ)+(M1*2*(REQ+RAD)))+M2*(3*(
+ $REQ+RAD+RMU)+4*(RMI)+M1*(2*(RAD)+REQ))
+ BR2=M2*(2*(REQ+RMI)+3*RMU+M1*(2*RAD+REQ))
+ TCPU=T1+T2+T3+T4+T5+T6+T7+T8+T9+T10
+ TCPU=TCPU+TNR+BT1+BT2
+ LIOF=M1/(N30)
+ IRZ=0
+ IF(LIOF*N30.EQ.M1) GOTO 2344
+ IRZ=1
+2344 IF(IRZ.EQ.0)TCPU=TCPU+BT3
+ IF(IRZ.NE.0)TCPU=TCPU+BT3+BR2
+ TIOOP=2.*FLOAT(M1)*FLOAT(M2)*TTRANS+2.*FLOAT(K2)*TACC+TCPU
+ IBOP=1
+ IBBOP=0
+ K3OP=1
+ TIOOP2=TCPU
+ TIOOP1=TIOOP-TCPU
+17 TTOT=TIOOP+TFF
+ IF(TTOT.LE.0.) GOTO 3
+ IF(TTOT.GE.TTOTOP)GOTO3
+ N1CO=N10
+ N2CO=N20
+ IBCO=IBOP
+ IBBCO=IBBOP
+ K3CO=K3OP
+ TTOTOP=TTOT
+ TESOP=TIOOP1
+ TCOP=TIOOP2
+ TFOP=TFF
+3 CONTINUE
+
+ N1=N1CO
+ N2=N2CO
+ TTO=TTOTOP
+ IB=IBCO
+ IBB=IBBCO
+ K3=K3CO
+ TC=TCOP
+ TS=TESOP
+ TF=TFOP
+ TT=TCOP+TFOP
+ TWER=TTO-TT
+ IF(N1.EQ.0.OR.N2.EQ.0) CALL OUTSTR(0,'PAS DE PLACE MEMOIRE SUFFISA
+ $NTE POUR UNE MISE EN OEUVRE PAR BLOCS$')
+ IF(IB.NE.1)RETURN
+ IHJ=(M1/(N1-L1+1))
+ IF(IHJ*(N1-L1+1).NE.M1)IHJ=IHJ+1
+ IHJ1=IHJ/2
+ IF(IHJ1*2.NE.IHJ)GOTO7778
+ IB=IHJ
+ IBB=0
+ RETURN
+7778 IB=IHJ+1
+ IBB=0
+ RETURN
+ END
Index: Fortran/gfortran/regression/g77/19990905-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990905-0.f
@@ -0,0 +1,12 @@
+c { dg-do compile }
+* =foo0.f in Burley's g77 test suite.
+! Used to give "Variable 'm' cannot appear" "Variable 'm' cannot appear"
+! after REAL a(m,n), as described in PR 16511.
+!
+ subroutine sub(a)
+ equivalence (m,iarray(100))
+ common /info/ iarray(1000)
+ equivalence (n,iarray(200))
+ real a(m,n)
+ a(1,1) = a(2,2)
+ end
Index: Fortran/gfortran/regression/g77/19990905-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990905-1.f
@@ -0,0 +1,19 @@
+c { dg-do compile }
+c
+c g77 gave error
+c 19990905-1.f: In subroutine `x':
+c 19990905-1.f:15:
+c common /foo/n
+c 1
+c 19990905-1.f:18: (continued):
+c call foo(a(1))
+c 2
+c Invalid declaration of or reference to symbol `foo' at (2) [initially seen at (1)]
+* =foo7.f in Burley's g77 test suite.
+ subroutine x
+ real a(n)
+ common /foo/n ! { dg-error "is already being used as a COMMON" }
+ continue
+ entry y(a)
+ call foo(a(1)) ! { dg-error "is already being used as a COMMON" }
+ end
Index: Fortran/gfortran/regression/g77/19990905-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/19990905-2.f
@@ -0,0 +1,23 @@
+c { dg-do compile }
+* =watson11.f in Burley's g77 test suite.
+* Probably originally submitted by Ian Watson.
+* Too small to worry about copyright issues, IMO, since it
+* doesn't do anything substantive.
+ SUBROUTINE OUTDNS(A,B,LCONV)
+ IMPLICIT REAL(kind=8) (A-H,O-Z),INTEGER(I-N)
+ COMMON/ARRAYS/Z(64,8),AB(30,30),PAIRS(9,9),T(9,9),TEMP(9,9),C1(3),
+ > C2(3),AA(30),BB(30)
+ EQUIVALENCE (X1,C1(1)),(Y1,C1(2)),(Z1,C1(3))
+ EQUIVALENCE (X2,C2(1)),(Y2,C2(2)),(Z2,C2(3))
+ COMMON /CONTRL/
+ > SHIFT,CONV,SCION,DIVERG,
+ > IOPT,KCNDO,KINDO,KMINDO,I2EINT,KOHNO,KSLATE,
+ > N,NG,NUMAT,NSEK,NELECS,NIT,OCCA,OCCB,NOLDAT,NOLDFN
+ INTEGER OCCA,OCCB
+ DIMENSION W(N),A(N,N),B(N,N)
+ DIMENSION BUF(100)
+ occb=5
+ ENTRY INDNS (A,B)
+ 40 READ(IREAD) BUF
+ STOP
+ END
Index: Fortran/gfortran/regression/g77/20000412-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000412-1.f
@@ -0,0 +1,6 @@
+c { dg-do compile }
+ subroutine aap(k)
+ equivalence (i,r)
+ i = k
+ print*,r
+ end
Index: Fortran/gfortran/regression/g77/20000503-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000503-1.f
@@ -0,0 +1,25 @@
+c { dg-do run }
+*
+* Originally derived from LAPACK 3.0 test suite failure.
+*
+* David Billinghurst, (David.Billinghurst@riotinto.com.au)
+* 23 February 2000
+*
+ INTEGER N, I, SLASQX
+ N = 20
+ I = SLASQX( N )
+ IF ( I .NE. 2*N ) THEN
+ WRITE(6,*) 'I = ', I, ' but should be ', 2*N
+ STOP 1
+ END IF
+ END
+
+ INTEGER FUNCTION SLASQX( N )
+ INTEGER N, I0, I, K
+ I0 = 1
+ DO I = 4*I0, 2*( I0+N-1 ), 4
+ K = I
+ END DO
+ SLASQX = K
+ RETURN
+ END
Index: Fortran/gfortran/regression/g77/20000511-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000511-1.f
@@ -0,0 +1,22 @@
+c { dg-do compile }
+ subroutine saxpy(n,sa,sx,incx,sy,incy)
+C
+C constant times a vector plus a vector.
+C uses unrolled loop for increments equal to one.
+C jack dongarra, linpack, 3/11/78.
+C modified 12/3/93, array(1) declarations changed to array(*)
+C
+ real sx(*),sy(*),sa
+ integer i,incx,incy,ix,iy,m,mp1,n
+C
+C -ffast-math ICE provoked by this conditional
+ if(sa /= 0.0)then
+C
+C code for both increments equal to 1
+C
+ do i= 1,n
+ sy(i)= sy(i)+sa*sx(i)
+ enddo
+ endif
+ return
+ end
Index: Fortran/gfortran/regression/g77/20000511-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000511-2.f
@@ -0,0 +1,62 @@
+c { dg-do compile }
+ subroutine sgbcon(norm,n,kl,ku,ab,ldab,ipiv,anorm,rcond,work,iwork
+ &,info)
+C
+C -- LAPACK routine (version 3.0) --
+C Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
+C Courant Institute, Argonne National Lab, and Rice University
+C September 30, 1994
+C
+C .. Scalar Arguments ..
+ character norm
+ integer info,kl,ku,ldab,n
+ real anorm,rcond
+C ..
+C .. Array Arguments ..
+ integer ipiv(n),iwork(n)
+ real ab(ldab,n),work(n)
+C ..
+C
+C Purpose
+C =======
+C demonstrate g77 bug at -O -funroll-loops
+C =====================================================================
+C
+C .. Parameters ..
+ real one,zero
+ parameter(one= 1.0e+0,zero= 0.0e+0)
+C ..
+C .. Local Scalars ..
+ logical lnoti,onenrm
+ character normin
+ integer ix,j,jp,kase,kase1,kd,lm
+ real ainvnm,scale,smlnum,t
+C ..
+C .. External Functions ..
+ logical lsame
+ integer isamax
+ real sdot,slamch
+ externallsame,isamax,sdot,slamch
+C ..
+C .. External Subroutines ..
+ externalsaxpy,slacon,slatbs,srscl,xerbla
+C ..
+C .. Executable Statements ..
+C
+C Multiply by inv(L).
+C
+ do j= 1,n-1
+C the following min() intrinsic provokes this bug
+ lm= min(kl,n-j)
+ jp= ipiv(j)
+ t= work(jp)
+ if(jp.ne.j)then
+C but only when combined with this if block
+ work(jp)= work(j)
+ work(j)= t
+ endif
+C and this subroutine call
+ call saxpy(lm,-t,ab(kd+1,j),1,work(j+1),1)
+ enddo
+ return
+ end
Index: Fortran/gfortran/regression/g77/20000518.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000518.f
@@ -0,0 +1,17 @@
+c { dg-do compile }
+ SUBROUTINE SORG2R( K, A, N, LDA )
+* ICE in `verify_wide_reg_1', at flow.c:2605 at -O2
+* g77 version 2.96 20000515 (experimental) on i686-pc-linux-gnu
+*
+* Originally derived from LAPACK 3.0 test suite failure.
+*
+* David Billinghurst, (David.Billinghurst@riotinto.com.au)
+* 18 May 2000
+ INTEGER I, K, LDA, N
+ REAL A( LDA, * )
+ DO I = K, 1, -1
+ IF( I.LT.N ) A( I, I ) = 1.0
+ A( I, I ) = 1.0
+ END DO
+ RETURN
+ END
Index: Fortran/gfortran/regression/g77/20000601-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000601-1.f
@@ -0,0 +1,29 @@
+c { dg-do compile }
+ SUBROUTINE SGBTRF( M, KL, KU, AB, LDAB )
+
+* PR fortran/275
+* ICE in `change_address', at emit-rtl.c:1589 with -O1 and above
+* g77 version 2.96 20000530 (experimental) on mips-sgi-irix6.5/-mabi=64
+*
+* Originally derived from LAPACK 3.0 test suite failure.
+*
+* David Billinghurst, (David.Billinghurst@riotinto.com.au)
+* 1 June 2000
+
+ INTEGER KL, KU, LDAB, M
+ REAL AB( LDAB, * )
+
+ INTEGER J, JB, JJ, JP, KV, KM
+ REAL WORK13(65,64), WORK31(65,64)
+ KV = KU + KL
+ DO J = 1, M
+ JB = MIN( 1, M-J+1 )
+ DO JJ = J, J + JB - 1
+ KM = MIN( KL, M-JJ )
+ JP = KM+1
+ CALL SSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1,
+ $ AB( KV+JP+JJ-J, J ), LDAB-1 )
+ END DO
+ END DO
+ RETURN
+ END
Index: Fortran/gfortran/regression/g77/20000601-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000601-2.f
@@ -0,0 +1,28 @@
+c { dg-do compile }
+ SUBROUTINE SGBTRF( M, KL, KU, AB, LDAB )
+
+* Slightly modified version of 20000601-1.f that still ICES with
+* CVS 20010118 g77 on mips-sgi-irix6.5/-mabi=64.
+*
+* Originally derived from LAPACK 3.0 test suite failure.
+*
+* David Billinghurst, (David.Billinghurst@riotinto.com.au)
+* 18 January 2001
+
+ INTEGER KL, KU, LDAB, M
+ REAL AB( LDAB, * )
+
+ INTEGER J, JB, JJ, JP, KV, KM, F
+ REAL WORK13(65,64), WORK31(65,64)
+ KV = KU + KL
+ DO J = 1, M
+ JB = MIN( 1, M-J+1 )
+ DO JJ = J, J + JB - 1
+ KM = MIN( KL, M-JJ )
+ JP = F( KM+1, AB( KV+1, JJ ) )
+ CALL SSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1,
+ $ AB( KV+JP+JJ-J, J ), LDAB-1 )
+ END DO
+ END DO
+ RETURN
+ END
Index: Fortran/gfortran/regression/g77/20000629-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000629-1.f
@@ -0,0 +1,12 @@
+c { dg-do compile }
+ SUBROUTINE MIST(N, BETA)
+ IMPLICIT REAL(kind=8) (A-H,O-Z)
+ INTEGER IA, IQ, M1
+ DIMENSION BETA(N)
+ DO 80 IQ=1,M1
+ IF (BETA(IQ).EQ.0.0D0) GO TO 120
+ 80 CONTINUE
+ 120 IF (IQ.NE.1) GO TO 160
+ 160 M1 = IA(IQ)
+ RETURN
+ END
Index: Fortran/gfortran/regression/g77/20000630-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20000630-2.f
@@ -0,0 +1,12 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+c
+ SUBROUTINE CHOUT(CHR,ICNT)
+C ICE: failed assertion `expr != NULL'
+C Reduced version of GNATS PR fortran/329 from trond.bo@dnmi.no
+ INTEGER CHR(ICNT)
+ CHARACTER*255 BUF
+ BUF(1:1)=CHAR(CHR(1))
+ CALL FPUTC(1,BUF(1:1))
+ RETURN
+ END
Index: Fortran/gfortran/regression/g77/20001111.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20001111.f
@@ -0,0 +1,13 @@
+c { dg-do run }
+ DOUBLE PRECISION VALUE(2), TOLD, BK
+ DATA VALUE /0D0, 1D0/
+ DATA TOLD /0D0/
+ DO I=1, 2
+ BK = VALUE(I)
+ IF(BK .GT. TOLD) GOTO 10
+ ENDDO
+ WRITE(*,*)'Error: BK = ', BK
+ STOP 1
+ 10 CONTINUE
+ WRITE(*,*)'No Error: BK = ', BK
+ END
Index: Fortran/gfortran/regression/g77/20010115.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010115.f
@@ -0,0 +1,10 @@
+c { dg-do compile }
+* GNATS PR Fortran/1636
+ PRINT 42, 'HELLO'
+ 42 FORMAT(A)
+ CALL WORLD
+ END
+ SUBROUTINE WORLD
+ PRINT 42, 'WORLD'
+ 42 FORMAT(A)
+ END
Index: Fortran/gfortran/regression/g77/20010116.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010116.f
@@ -0,0 +1,41 @@
+c { dg-do run }
+c { dg-options "-std=legacy" }
+c
+*
+* Derived from LAPACK 3.0 routine CHGEQZ
+* Fails on i686-pc-cygwin with gcc-2.97 snapshots at -O2 and higher
+* PR fortran/1645
+*
+* David Billinghurst, (David.Billinghurst@riotinto.com)
+* 14 January 2001
+* Rewritten by Toon Moene (toon@moene.indiv.nluug.nl)
+* 15 January 2001
+*
+ COMPLEX A(5,5)
+ DATA A/25*(0.0,0.0)/
+ A(4,3) = (0.05,0.2)/3.0E-7
+ A(4,4) = (-0.03,-0.4)
+ A(5,4) = (-2.0E-07,2.0E-07)
+ CALL CHGEQZ( 5, A )
+ END
+ SUBROUTINE CHGEQZ( N, A )
+ COMPLEX A(N,N), X
+ ABS1( X ) = ABS( REAL( X ) ) + ABS( AIMAG( X ) )
+ DO J = 4, 2, -1
+ I = J
+ TEMP = ABS1( A(J,J) )
+ TEMP2 = ABS1( A( J+1, J ) )
+ TEMPR = MAX( TEMP, TEMP2 )
+ IF( TEMPR .LT. 1.0 .AND. TEMPR .NE. 0.0 ) THEN
+ TEMP = TEMP / TEMPR
+ TEMP2 = TEMP2 / TEMPR
+ END IF
+ IF ( ABS1(A(J,J-1))*TEMP2 .LE. TEMP ) GO TO 90
+ END DO
+c Should not reach here, but need a statement
+ PRINT*
+ 90 IF ( I .NE. 4 ) THEN
+ PRINT*,'I =', I, ' but should be 4'
+ STOP 1
+ END IF
+ END
Index: Fortran/gfortran/regression/g77/20010216-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010216-1.f
@@ -0,0 +1,52 @@
+C Test for bug in reg-stack handling conditional moves.
+C Reported by Tim Prince
+C
+C { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+C { dg-options "-ffast-math -march=pentiumpro" }
+
+ double precision function foo(x, y)
+ implicit none
+ double precision x, y
+ double precision a, b, c, d
+ if (x /= y) then
+ if (x * y >= 0) then
+ a = abs(x)
+ b = abs(y)
+ c = max(a, b)
+ d = min(a, b)
+ foo = 1 - d/c
+ else
+ foo = 1
+ end if
+ else
+ foo = 0
+ end if
+ end
+
+ program test
+ implicit none
+
+ integer ntests
+ parameter (ntests=7)
+ double precision tolerance
+ parameter (tolerance=1.0D-6)
+
+C Each column is a pair of values to feed to foo,
+C and its expected return value.
+ double precision a(ntests), b(ntests), x(ntests)
+ data a /1, -23, -1, 1, 9, 10, -9/
+ data b /1, -23, 12, -12, 10, 9, -10/
+ data x /0, 0, 1, 1, 0.1, 0.1, 0.1/
+
+ double precision foo
+ double precision result
+ integer i
+
+ do i = 1, ntests
+ result = foo(a(i), b(i))
+ if (abs(result - x(i)) > tolerance) then
+ print *, i, a(i), b(i), x(i), result
+ STOP 1
+ end if
+ end do
+ end
Index: Fortran/gfortran/regression/g77/20010321-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010321-1.f
@@ -0,0 +1,9 @@
+c { dg-do compile }
+# 1 "20010321-1.f"
+ SUBROUTINE TWOEXP
+# 1 "include/implicit.h" 1 3
+ IMPLICIT DOUBLE PRECISION (A-H)
+# 3 "20010321-1.f" 2 3
+ LOGICAL ANTI
+ ANTI = .FALSE.
+ END
Index: Fortran/gfortran/regression/g77/20010426-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010426-1.f
@@ -0,0 +1,3 @@
+c { dg-do run }
+ print*,cos(1.0)
+ end
Index: Fortran/gfortran/regression/g77/20010426.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010426.f
@@ -0,0 +1,7 @@
+c { dg-do compile }
+ function f(c)
+ implicit none
+ real(kind=8) c, f
+ f = sqrt(c)
+ return
+ end
Index: Fortran/gfortran/regression/g77/20010430.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010430.f
@@ -0,0 +1,21 @@
+c { dg-do run }
+ REAL DAT(2,5)
+ DO I = 1, 5
+ DAT(1,I) = I*1.6356-NINT(I*1.6356)
+ DAT(2,I) = I
+ ENDDO
+ DO I = 1, 4
+ DO J = I+1, 5
+ IF (DAT(1,J) - DAT(1,I) .LT. 0.0) THEN
+ DO K = 1, 2
+ TMP = DAT(K,I)
+ DAT(K,I) = DAT(K,J)
+ DAT(K,J) = TMP
+ ENDDO
+ ENDIF
+ ENDDO
+ ENDDO
+ DO I = 1, 4
+ IF (DAT(1,I) .GT. DAT(1,I+1)) STOP 1
+ ENDDO
+ END
Index: Fortran/gfortran/regression/g77/20010519-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010519-1.f
@@ -0,0 +1,1328 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+CHARMM Element source/dimb/nmdimb.src 1.1
+C.##IF DIMB
+ SUBROUTINE NMDIMB(X,Y,Z,NAT3,BNBND,BIMAG,LNOMA,AMASS,DDS,DDSCR,
+ 1 PARDDV,DDV,DDM,PARDDF,DDF,PARDDE,DDEV,DD1BLK,
+ 2 DD1BLL,NADD,LRAISE,DD1CMP,INBCMP,JNBCMP,
+ 3 NPAR,ATMPAR,ATMPAS,BLATOM,PARDIM,NFREG,NFRET,
+ 4 PARFRQ,CUTF1,ITMX,TOLDIM,IUNMOD,IUNRMD,
+ 5 LBIG,LSCI,ATMPAD,SAVF,NBOND,IB,JB,DDVALM)
+C-----------------------------------------------------------------------
+C 01-Jul-1992 David Perahia, Liliane Mouawad
+C 15-Dec-1994 Herman van Vlijmen
+C
+C This is the main routine for the mixed-basis diagonalization.
+C See: L.Mouawad and D.Perahia, Biopolymers (1993), 33, 599,
+C and: D.Perahia and L.Mouawad, Comput. Chem. (1995), 19, 241.
+C The method iteratively solves the diagonalization of the
+C Hessian matrix. To save memory space, it uses a compressed
+C form of the Hessian, which only contains the nonzero elements.
+C In the diagonalization process, approximate eigenvectors are
+C mixed with Cartesian coordinates to form a reduced basis. The
+C Hessian is then diagonalized in the reduced basis. By iterating
+C over different sets of Cartesian coordinates the method ultimately
+C converges to the exact eigenvalues and eigenvectors (up to the
+C requested accuracy).
+C If no existing basis set is read, an initial basis will be created
+C which consists of the low-frequency eigenvectors of diagonal blocks
+C of the Hessian.
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/impnon.fcm'
+C..##IF VAX IRIS HPUX IRIS GNU CSPP OS2 GWS CRAY ALPHA
+ IMPLICIT NONE
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/stream.fcm'
+ LOGICAL LOWER,QLONGL
+ INTEGER MXSTRM,POUTU
+ PARAMETER (MXSTRM=20,POUTU=6)
+ INTEGER NSTRM,ISTRM,JSTRM,OUTU,PRNLEV,WRNLEV,IOLEV
+ COMMON /CASE/ LOWER, QLONGL
+ COMMON /STREAM/ NSTRM,ISTRM,JSTRM(MXSTRM),OUTU,PRNLEV,WRNLEV,IOLEV
+C..##IF SAVEFCM
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/dimens.fcm'
+ INTEGER LARGE,MEDIUM,SMALL,REDUCE
+C..##IF QUANTA
+C..##ELIF T3D
+C..##ELSE
+ PARAMETER (LARGE=60120, MEDIUM=25140, SMALL=6120)
+C..##ENDIF
+ PARAMETER (REDUCE=15000)
+ INTEGER SIZE
+C..##IF XLARGE
+C..##ELIF XXLARGE
+C..##ELIF LARGE
+C..##ELIF MEDIUM
+ PARAMETER (SIZE=MEDIUM)
+C..##ELIF REDUCE
+C..##ELIF SMALL
+C..##ELIF XSMALL
+C..##ENDIF
+C..##IF MMFF
+ integer MAXDEFI
+ parameter(MAXDEFI=250)
+ INTEGER NAME0,NAMEQ0,NRES0,KRES0
+ PARAMETER (NAME0=4,NAMEQ0=10,NRES0=4,KRES0=4)
+ integer MaxAtN
+ parameter (MaxAtN=55)
+ INTEGER MAXAUX
+ PARAMETER (MAXAUX = 10)
+C..##ENDIF
+ INTEGER MAXCSP, MAXHSET
+C..##IF HMCM
+ PARAMETER (MAXHSET = 200)
+C..##ELSE
+C..##ENDIF
+C..##IF REDUCE
+C..##ELSE
+ PARAMETER (MAXCSP = 500)
+C..##ENDIF
+C..##IF HMCM
+ INTEGER MAXHCM,MAXPCM,MAXRCM
+C...##IF REDUCE
+C...##ELSE
+ PARAMETER (MAXHCM=500)
+ PARAMETER (MAXPCM=5000)
+ PARAMETER (MAXRCM=2000)
+C...##ENDIF
+C..##ENDIF
+ INTEGER MXCMSZ
+C..##IF IBM IBMRS CRAY INTEL IBMSP T3D REDUCE
+C..##ELSE
+ PARAMETER (MXCMSZ = 5000)
+C..##ENDIF
+ INTEGER CHRSIZ
+ PARAMETER (CHRSIZ = SIZE)
+ INTEGER MAXATB
+C..##IF REDUCE
+C..##ELIF QUANTA
+C..##ELSE
+ PARAMETER (MAXATB = 200)
+C..##ENDIF
+ INTEGER MAXVEC
+C..##IFN VECTOR PARVECT
+ PARAMETER (MAXVEC = 10)
+C..##ELIF LARGE XLARGE XXLARGE
+C..##ELIF MEDIUM
+C..##ELIF SMALL REDUCE
+C..##ELIF XSMALL
+C..##ELSE
+C..##ENDIF
+ INTEGER IATBMX
+ PARAMETER (IATBMX = 8)
+ INTEGER MAXHB
+C..##IF LARGE XLARGE XXLARGE
+C..##ELIF MEDIUM
+ PARAMETER (MAXHB = 8000)
+C..##ELIF SMALL
+C..##ELIF REDUCE XSMALL
+C..##ELSE
+C..##ENDIF
+ INTEGER MAXTRN,MAXSYM
+C..##IFN NOIMAGES
+ PARAMETER (MAXTRN = 5000)
+ PARAMETER (MAXSYM = 192)
+C..##ELSE
+C..##ENDIF
+C..##IF LONEPAIR (lonepair_max)
+ INTEGER MAXLP,MAXLPH
+C...##IF REDUCE
+C...##ELSE
+ PARAMETER (MAXLP = 2000)
+ PARAMETER (MAXLPH = 4000)
+C...##ENDIF
+C..##ENDIF (lonepair_max)
+ INTEGER NOEMAX,NOEMX2
+C..##IF REDUCE
+C..##ELSE
+ PARAMETER (NOEMAX = 2000)
+ PARAMETER (NOEMX2 = 4000)
+C..##ENDIF
+ INTEGER MAXATC, MAXCB, MAXCH, MAXCI, MAXCP, MAXCT, MAXITC, MAXNBF
+C..##IF REDUCE
+C..##ELIF MMFF CFF
+ PARAMETER (MAXATC = 500, MAXCB = 1500, MAXCH = 3200, MAXCI = 600,
+ & MAXCP = 3000,MAXCT = 15500,MAXITC = 200, MAXNBF=1000)
+C..##ELIF YAMMP
+C..##ELIF LARGE
+C..##ELSE
+C..##ENDIF
+ INTEGER MAXCN
+ PARAMETER (MAXCN = MAXITC*(MAXITC+1)/2)
+ INTEGER MAXA, MAXAIM, MAXB, MAXT, MAXP
+ INTEGER MAXIMP, MAXNB, MAXPAD, MAXRES
+ INTEGER MAXSEG, MAXGRP
+C..##IF LARGE XLARGE XXLARGE
+C..##ELIF MEDIUM
+ PARAMETER (MAXA = SIZE, MAXB = SIZE, MAXT = SIZE,
+ & MAXP = 2*SIZE)
+ PARAMETER (MAXIMP = 9200, MAXNB = 17200, MAXPAD = 8160,
+ & MAXRES = 14000)
+C...##IF MCSS
+C...##ELSE
+ PARAMETER (MAXSEG = 1000)
+C...##ENDIF
+C..##ELIF SMALL
+C..##ELIF XSMALL
+C..##ELIF REDUCE
+C..##ELSE
+C..##ENDIF
+C..##IF NOIMAGES
+C..##ELSE
+ PARAMETER (MAXAIM = 2*SIZE)
+ PARAMETER (MAXGRP = 2*SIZE/3)
+C..##ENDIF
+ INTEGER REDMAX,REDMX2
+C..##IF REDUCE
+C..##ELSE
+ PARAMETER (REDMAX = 20)
+ PARAMETER (REDMX2 = 80)
+C..##ENDIF
+ INTEGER MXRTRS, MXRTA, MXRTB, MXRTT, MXRTP, MXRTI, MXRTX,
+ & MXRTHA, MXRTHD, MXRTBL, NICM
+ PARAMETER (MXRTRS = 200, MXRTA = 5000, MXRTB = 5000,
+ & MXRTT = 5000, MXRTP = 5000, MXRTI = 2000,
+C..##IF YAMMP
+C..##ELSE
+ & MXRTX = 5000, MXRTHA = 300, MXRTHD = 300,
+C..##ENDIF
+ & MXRTBL = 5000, NICM = 10)
+ INTEGER NMFTAB, NMCTAB, NMCATM, NSPLIN
+C..##IF REDUCE
+C..##ELSE
+ PARAMETER (NMFTAB = 200, NMCTAB = 3, NMCATM = 12000, NSPLIN = 3)
+C..##ENDIF
+ INTEGER MAXSHK
+C..##IF XSMALL
+C..##ELIF REDUCE
+C..##ELSE
+ PARAMETER (MAXSHK = SIZE*3/4)
+C..##ENDIF
+ INTEGER SCRMAX
+C..##IF IBM IBMRS CRAY INTEL IBMSP T3D REDUCE
+C..##ELSE
+ PARAMETER (SCRMAX = 5000)
+C..##ENDIF
+C..##IF TSM
+ INTEGER MXPIGG
+C...##IF REDUCE
+C...##ELSE
+ PARAMETER (MXPIGG=500)
+C...##ENDIF
+ INTEGER MXCOLO,MXPUMB
+ PARAMETER (MXCOLO=20,MXPUMB=20)
+C..##ENDIF
+C..##IF ADUMB
+ INTEGER MAXUMP, MAXEPA, MAXNUM
+C...##IF REDUCE
+C...##ELSE
+ PARAMETER (MAXUMP = 10, MAXNUM = 4)
+C...##ENDIF
+C..##ENDIF
+ INTEGER MAXING
+ PARAMETER (MAXING=1000)
+C..##IF MMFF
+ integer MAX_RINGSIZE, MAX_EACH_SIZE
+ parameter (MAX_RINGSIZE = 20, MAX_EACH_SIZE = 1000)
+ integer MAXPATHS
+ parameter (MAXPATHS = 8000)
+ integer MAX_TO_SEARCH
+ parameter (MAX_TO_SEARCH = 6)
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/number.fcm'
+ REAL(KIND=8) ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX,
+ & SEVEN, EIGHT, NINE, TEN, ELEVEN, TWELVE, THIRTN,
+ & FIFTN, NINETN, TWENTY, THIRTY
+C..##IF SINGLE
+C..##ELSE
+ PARAMETER (ZERO = 0.D0, ONE = 1.D0, TWO = 2.D0,
+ & THREE = 3.D0, FOUR = 4.D0, FIVE = 5.D0,
+ & SIX = 6.D0, SEVEN = 7.D0, EIGHT = 8.D0,
+ & NINE = 9.D0, TEN = 10.D0, ELEVEN = 11.D0,
+ & TWELVE = 12.D0, THIRTN = 13.D0, FIFTN = 15.D0,
+ & NINETN = 19.D0, TWENTY = 20.D0, THIRTY = 30.D0)
+C..##ENDIF
+ REAL(KIND=8) FIFTY, SIXTY, SVNTY2, EIGHTY, NINETY, HUNDRD,
+ & ONE2TY, ONE8TY, THRHUN, THR6TY, NINE99, FIFHUN, THOSND,
+ & FTHSND,MEGA
+C..##IF SINGLE
+C..##ELSE
+ PARAMETER (FIFTY = 50.D0, SIXTY = 60.D0, SVNTY2 = 72.D0,
+ & EIGHTY = 80.D0, NINETY = 90.D0, HUNDRD = 100.D0,
+ & ONE2TY = 120.D0, ONE8TY = 180.D0, THRHUN = 300.D0,
+ & THR6TY=360.D0, NINE99 = 999.D0, FIFHUN = 1500.D0,
+ & THOSND = 1000.D0,FTHSND = 5000.D0, MEGA = 1.0D6)
+C..##ENDIF
+ REAL(KIND=8) MINONE, MINTWO, MINSIX
+ PARAMETER (MINONE = -1.D0, MINTWO = -2.D0, MINSIX = -6.D0)
+ REAL(KIND=8) TENM20,TENM14,TENM8,TENM5,PT0001,PT0005,PT001,PT005,
+ & PT01, PT02, PT05, PTONE, PT125, PT25, SIXTH, THIRD,
+ & PTFOUR, PTSIX, HALF, PT75, PT9999, ONEPT5, TWOPT4
+C..##IF SINGLE
+C..##ELSE
+ PARAMETER (TENM20 = 1.0D-20, TENM14 = 1.0D-14, TENM8 = 1.0D-8,
+ & TENM5 = 1.0D-5, PT0001 = 1.0D-4, PT0005 = 5.0D-4,
+ & PT001 = 1.0D-3, PT005 = 5.0D-3, PT01 = 0.01D0,
+ & PT02 = 0.02D0, PT05 = 0.05D0, PTONE = 0.1D0,
+ & PT125 = 0.125D0, SIXTH = ONE/SIX,PT25 = 0.25D0,
+ & THIRD = ONE/THREE,PTFOUR = 0.4D0, HALF = 0.5D0,
+ & PTSIX = 0.6D0, PT75 = 0.75D0, PT9999 = 0.9999D0,
+ & ONEPT5 = 1.5D0, TWOPT4 = 2.4D0)
+C..##ENDIF
+ REAL(KIND=8) ANUM,FMARK
+ REAL(KIND=8) RSMALL,RBIG
+C..##IF SINGLE
+C..##ELSE
+ PARAMETER (ANUM=9999.0D0, FMARK=-999.0D0)
+ PARAMETER (RSMALL=1.0D-10,RBIG=1.0D20)
+C..##ENDIF
+ REAL(KIND=8) RPRECI,RBIGST
+C..##IF VAX DEC
+C..##ELIF IBM
+C..##ELIF CRAY
+C..##ELIF ALPHA T3D T3E
+C..##ELSE
+C...##IF SINGLE
+C...##ELSE
+ PARAMETER (RPRECI = 2.22045D-16, RBIGST = 4.49423D+307)
+C...##ENDIF
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/consta.fcm'
+ REAL(KIND=8) PI,RADDEG,DEGRAD,TWOPI
+ PARAMETER(PI=3.141592653589793D0,TWOPI=2.0D0*PI)
+ PARAMETER (RADDEG=180.0D0/PI)
+ PARAMETER (DEGRAD=PI/180.0D0)
+ REAL(KIND=8) COSMAX
+ PARAMETER (COSMAX=0.9999999999D0)
+ REAL(KIND=8) TIMFAC
+ PARAMETER (TIMFAC=4.88882129D-02)
+ REAL(KIND=8) KBOLTZ
+ PARAMETER (KBOLTZ=1.987191D-03)
+ REAL(KIND=8) CCELEC
+C..##IF AMBER
+C..##ELIF DISCOVER
+C..##ELSE
+ PARAMETER (CCELEC=332.0716D0)
+C..##ENDIF
+ REAL(KIND=8) CNVFRQ
+ PARAMETER (CNVFRQ=2045.5D0/(2.99793D0*6.28319D0))
+ REAL(KIND=8) SPEEDL
+ PARAMETER (SPEEDL=2.99793D-02)
+ REAL(KIND=8) ATMOSP
+ PARAMETER (ATMOSP=1.4584007D-05)
+ REAL(KIND=8) PATMOS
+ PARAMETER (PATMOS = 1.D0 / ATMOSP )
+ REAL(KIND=8) BOHRR
+ PARAMETER (BOHRR = 0.529177249D0 )
+ REAL(KIND=8) TOKCAL
+ PARAMETER (TOKCAL = 627.5095D0 )
+C..##IF MMFF
+ REAL(KIND=8) MDAKCAL
+ parameter(MDAKCAL=143.9325D0)
+C..##ENDIF
+ REAL(KIND=8) DEBYEC
+ PARAMETER ( DEBYEC = 2.541766D0 / BOHRR )
+ REAL(KIND=8) ZEROC
+ PARAMETER ( ZEROC = 298.15D0 )
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/exfunc.fcm'
+C..##IF ACE
+C..##ENDIF
+C..##IF ADUMB
+C..##ENDIF
+ CHARACTER(4) GTRMA, NEXTA4, CURRA4
+ CHARACTER(6) NEXTA6
+ CHARACTER(8) NEXTA8
+ CHARACTER(20) NEXT20
+ INTEGER ALLCHR, ALLSTK, ALLHP, DECODI, FIND52,
+ * GETATN, GETRES, GETRSN, GETSEG, GTRMI, I4VAL,
+ * ICHAR4, ICMP16, ILOGI4, INDX, INDXA, INDXAF,
+ * INDXRA, INTEG4, IREAL4, IREAL8, LOCDIF,
+ * LUNASS, MATOM, NEXTI, NINDX, NSELCT, NSELCTV, ATMSEL,
+ * PARNUM, PARINS,
+ * SRCHWD, SRCHWS, STRLNG, DSIZE, SSIZE
+C..##IF ACE
+ * ,GETNNB
+C..##ENDIF
+ LOGICAL CHKPTR, EQST, EQSTA, EQSTWC, EQWDWC, DOTRIM, CHECQUE,
+ * HYDROG, INITIA, LONE, LTSTEQ, ORDER, ORDER5,
+ * ORDERR, USEDDT, QTOKDEL, QDIGIT, QALPHA
+ REAL(KIND=8) DECODF, DOTVEC, GTRMF, LENVEC, NEXTF, RANDOM, GTRR8,
+ * RANUMB, R8VAL, RETVAL8, SUMVEC
+C..##IF ADUMB
+ * ,UMFI
+C..##ENDIF
+ EXTERNAL GTRMA, NEXTA4, CURRA4, NEXTA6, NEXTA8,NEXT20,
+ * ALLCHR, ALLSTK, ALLHP, DECODI, FIND52,
+ * GETATN, GETRES, GETRSN, GETSEG, GTRMI, I4VAL,
+ * ICHAR4, ICMP16, ILOGI4, INDX, INDXA, INDXAF,
+ * INDXRA, INTEG4, IREAL4, IREAL8, LOCDIF,
+ * LUNASS, MATOM, NEXTI, NINDX, NSELCT, NSELCTV, ATMSEL,
+ * PARNUM, PARINS,
+ * SRCHWD, SRCHWS, STRLNG, DSIZE, SSIZE,
+ * CHKPTR, EQST, EQSTA, EQSTWC, EQWDWC, DOTRIM, CHECQUE,
+ * HYDROG, INITIA, LONE, LTSTEQ, ORDER, ORDER5,
+ * ORDERR, USEDDT, QTOKDEL, QDIGIT, QALPHA,
+ * DECODF, DOTVEC, GTRMF, LENVEC, NEXTF, RANDOM, GTRR8,
+ * RANUMB, R8VAL, RETVAL8, SUMVEC
+C..##IF ADUMB
+ * ,UMFI
+C..##ENDIF
+C..##IF ACE
+ * ,GETNNB
+C..##ENDIF
+C..##IFN NOIMAGES
+ INTEGER IMATOM
+ EXTERNAL IMATOM
+C..##ENDIF
+C..##IF MBOND
+C..##ENDIF
+C..##IF MMFF
+ INTEGER LEN_TRIM
+ EXTERNAL LEN_TRIM
+ CHARACTER(4) AtName
+ external AtName
+ CHARACTER(8) ElementName
+ external ElementName
+ CHARACTER(10) QNAME
+ external QNAME
+ integer IATTCH, IBORDR, CONN12, CONN13, CONN14
+ integer LEQUIV, LPATH
+ integer nbndx, nbnd2, nbnd3, NTERMA
+ external IATTCH, IBORDR, CONN12, CONN13, CONN14
+ external LEQUIV, LPATH
+ external nbndx, nbnd2, nbnd3, NTERMA
+ external find_loc
+ REAL(KIND=8) vangle, OOPNGL, TORNGL, ElementMass
+ external vangle, OOPNGL, TORNGL, ElementMass
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/stack.fcm'
+ INTEGER STKSIZ
+C..##IFN UNICOS
+C...##IF LARGE XLARGE
+C...##ELIF MEDIUM REDUCE
+ PARAMETER (STKSIZ=4000000)
+C...##ELIF SMALL
+C...##ELIF XSMALL
+C...##ELIF XXLARGE
+C...##ELSE
+C...##ENDIF
+ INTEGER LSTUSD,MAXUSD,STACK
+ COMMON /ISTACK/ LSTUSD,MAXUSD,STACK(STKSIZ)
+C..##ELSE
+C..##ENDIF
+C..##IF SAVEFCM
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/heap.fcm'
+ INTEGER HEAPDM
+C..##IFN UNICOS (unicos)
+C...##IF XXLARGE (size)
+C...##ELIF LARGE XLARGE (size)
+C...##ELIF MEDIUM (size)
+C....##IF T3D (t3d2)
+C....##ELIF TERRA (t3d2)
+C....##ELIF ALPHA (t3d2)
+C....##ELIF T3E (t3d2)
+C....##ELSE (t3d2)
+ PARAMETER (HEAPDM=2048000)
+C....##ENDIF (t3d2)
+C...##ELIF SMALL (size)
+C...##ELIF REDUCE (size)
+C...##ELIF XSMALL (size)
+C...##ELSE (size)
+C...##ENDIF (size)
+ INTEGER FREEHP,HEAPSZ,HEAP
+ COMMON /HEAPST/ FREEHP,HEAPSZ,HEAP(HEAPDM)
+ LOGICAL LHEAP(HEAPDM)
+ EQUIVALENCE (LHEAP,HEAP)
+C..##ELSE (unicos)
+C..##ENDIF (unicos)
+C..##IF SAVEFCM (save)
+C..##ENDIF (save)
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/fast.fcm'
+ INTEGER IACNB, NITCC, ICUSED, FASTER, LFAST, LMACH, OLMACH
+ INTEGER ICCOUNT, LOWTP, IGCNB, NITCC2
+ INTEGER ICCNBA, ICCNBB, ICCNBC, ICCNBD, LCCNBA, LCCNBD
+ COMMON /FASTI/ FASTER, LFAST, LMACH, OLMACH, NITCC, NITCC2,
+ & ICUSED(MAXATC), ICCOUNT(MAXATC), LOWTP(MAXATC),
+ & IACNB(MAXAIM), IGCNB(MAXATC),
+ & ICCNBA, ICCNBB, ICCNBC, ICCNBD, LCCNBA, LCCNBD
+C..##IF SAVEFCM
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/deriv.fcm'
+ REAL(KIND=8) DX,DY,DZ
+ COMMON /DERIVR/ DX(MAXAIM),DY(MAXAIM),DZ(MAXAIM)
+C..##IF SAVEFCM
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/energy.fcm'
+ INTEGER LENENP, LENENT, LENENV, LENENA
+ PARAMETER (LENENP = 50, LENENT = 70, LENENV = 50,
+ & LENENA = LENENP + LENENT + LENENV )
+ INTEGER TOTE, TOTKE, EPOT, TEMPS, GRMS, BPRESS, PJNK1, PJNK2,
+ & PJNK3, PJNK4, HFCTE, HFCKE, EHFC, EWORK, VOLUME, PRESSE,
+ & PRESSI, VIRI, VIRE, VIRKE, TEPR, PEPR, KEPR, KEPR2,
+ & DROFFA,
+ & XTLTE, XTLKE, XTLPE, XTLTEM, XTLPEP, XTLKEP, XTLKP2,
+ & TOT4, TOTK4, EPOT4, TEM4, MbMom, BodyT, PartT
+C..##IF ACE
+ & , SELF, SCREEN, COUL ,SOLV, INTER
+C..##ENDIF
+C..##IF FLUCQ
+ & ,FQKIN
+C..##ENDIF
+ PARAMETER (TOTE = 1, TOTKE = 2, EPOT = 3, TEMPS = 4,
+ & GRMS = 5, BPRESS = 6, PJNK1 = 7, PJNK2 = 8,
+ & PJNK3 = 9, PJNK4 = 10, HFCTE = 11, HFCKE = 12,
+ & EHFC = 13, EWORK = 11, VOLUME = 15, PRESSE = 16,
+ & PRESSI = 17, VIRI = 18, VIRE = 19, VIRKE = 20,
+ & TEPR = 21, PEPR = 22, KEPR = 23, KEPR2 = 24,
+ & DROFFA = 26, XTLTE = 27, XTLKE = 28,
+ & XTLPE = 29, XTLTEM = 30, XTLPEP = 31, XTLKEP = 32,
+ & XTLKP2 = 33,
+ & TOT4 = 37, TOTK4 = 38, EPOT4 = 39, TEM4 = 40,
+ & MbMom = 41, BodyT = 42, PartT = 43
+C..##IF ACE
+ & , SELF = 45, SCREEN = 46, COUL = 47,
+ & SOLV = 48, INTER = 49
+C..##ENDIF
+C..##IF FLUCQ
+ & ,FQKIN = 50
+C..##ENDIF
+ & )
+C..##IF ACE
+C..##ENDIF
+C..##IF GRID
+C..##ENDIF
+C..##IF FLUCQ
+C..##ENDIF
+ INTEGER BOND, ANGLE, UREYB, DIHE, IMDIHE, VDW, ELEC, HBOND,
+ & USER, CHARM, CDIHE, CINTCR, CQRT, NOE, SBNDRY,
+ & IMVDW, IMELEC, IMHBND, EWKSUM, EWSELF, EXTNDE, RXNFLD,
+ & ST2, IMST2, TSM, QMEL, QMVDW, ASP, EHARM, GEO, MDIP,
+ & PRMS, PANG, SSBP, BK4D, SHEL, RESD, SHAP,
+ & STRB, OOPL, PULL, POLAR, DMC, RGY, EWEXCL, EWQCOR,
+ & EWUTIL, PBELEC, PBNP, PINT, MbDefrm, MbElec, STRSTR,
+ & BNDBND, BNDTW, EBST, MBST, BBT, SST, GBEnr, GSBP
+C..##IF HMCM
+ & , HMCM
+C..##ENDIF
+C..##IF ADUMB
+ & , ADUMB
+C..##ENDIF
+ & , HYDR
+C..##IF FLUCQ
+ & , FQPOL
+C..##ENDIF
+ PARAMETER (BOND = 1, ANGLE = 2, UREYB = 3, DIHE = 4,
+ & IMDIHE = 5, VDW = 6, ELEC = 7, HBOND = 8,
+ & USER = 9, CHARM = 10, CDIHE = 11, CINTCR = 12,
+ & CQRT = 13, NOE = 14, SBNDRY = 15, IMVDW = 16,
+ & IMELEC = 17, IMHBND = 18, EWKSUM = 19, EWSELF = 20,
+ & EXTNDE = 21, RXNFLD = 22, ST2 = 23, IMST2 = 24,
+ & TSM = 25, QMEL = 26, QMVDW = 27, ASP = 28,
+ & EHARM = 29, GEO = 30, MDIP = 31, PINT = 32,
+ & PRMS = 33, PANG = 34, SSBP = 35, BK4D = 36,
+ & SHEL = 37, RESD = 38, SHAP = 39, STRB = 40,
+ & OOPL = 41, PULL = 42, POLAR = 43, DMC = 44,
+ & RGY = 45, EWEXCL = 46, EWQCOR = 47, EWUTIL = 48,
+ & PBELEC = 49, PBNP = 50, MbDefrm= 51, MbElec = 52,
+ & STRSTR = 53, BNDBND = 54, BNDTW = 55, EBST = 56,
+ & MBST = 57, BBT = 58, SST = 59, GBEnr = 60,
+ & GSBP = 65
+C..##IF HMCM
+ & , HMCM = 61
+C..##ENDIF
+C..##IF ADUMB
+ & , ADUMB = 62
+C..##ENDIF
+ & , HYDR = 63
+C..##IF FLUCQ
+ & , FQPOL = 65
+C..##ENDIF
+ & )
+ INTEGER VEXX, VEXY, VEXZ, VEYX, VEYY, VEYZ, VEZX, VEZY, VEZZ,
+ & VIXX, VIXY, VIXZ, VIYX, VIYY, VIYZ, VIZX, VIZY, VIZZ,
+ & PEXX, PEXY, PEXZ, PEYX, PEYY, PEYZ, PEZX, PEZY, PEZZ,
+ & PIXX, PIXY, PIXZ, PIYX, PIYY, PIYZ, PIZX, PIZY, PIZZ
+ PARAMETER ( VEXX = 1, VEXY = 2, VEXZ = 3, VEYX = 4,
+ & VEYY = 5, VEYZ = 6, VEZX = 7, VEZY = 8,
+ & VEZZ = 9,
+ & VIXX = 10, VIXY = 11, VIXZ = 12, VIYX = 13,
+ & VIYY = 14, VIYZ = 15, VIZX = 16, VIZY = 17,
+ & VIZZ = 18,
+ & PEXX = 19, PEXY = 20, PEXZ = 21, PEYX = 22,
+ & PEYY = 23, PEYZ = 24, PEZX = 25, PEZY = 26,
+ & PEZZ = 27,
+ & PIXX = 28, PIXY = 29, PIXZ = 30, PIYX = 31,
+ & PIYY = 32, PIYZ = 33, PIZX = 34, PIZY = 35,
+ & PIZZ = 36)
+ CHARACTER(4) CEPROP, CETERM, CEPRSS
+ COMMON /ANER/ CEPROP(LENENP), CETERM(LENENT), CEPRSS(LENENV)
+ LOGICAL QEPROP, QETERM, QEPRSS
+ COMMON /QENER/ QEPROP(LENENP), QETERM(LENENT), QEPRSS(LENENV)
+ REAL(KIND=8) EPROP, ETERM, EPRESS
+ COMMON /ENER/ EPROP(LENENP), ETERM(LENENT), EPRESS(LENENV)
+C..##IF SAVEFCM
+C..##ENDIF
+ REAL(KIND=8) EPRPA, EPRP2A, EPRPP, EPRP2P,
+ & ETRMA, ETRM2A, ETRMP, ETRM2P,
+ & EPRSA, EPRS2A, EPRSP, EPRS2P
+ COMMON /ENACCM/ EPRPA(LENENP), ETRMA(LENENT), EPRSA(LENENV),
+ & EPRP2A(LENENP),ETRM2A(LENENT),EPRS2A(LENENV),
+ & EPRPP(LENENP), ETRMP(LENENT), EPRSP(LENENV),
+ & EPRP2P(LENENP),ETRM2P(LENENT),EPRS2P(LENENV)
+C..##IF SAVEFCM
+C..##ENDIF
+ INTEGER ECALLS, TOT1ST, TOT2ND
+ COMMON /EMISCI/ ECALLS, TOT1ST, TOT2ND
+ REAL(KIND=8) EOLD, FITA, DRIFTA, EAT0A, CORRA, FITP, DRIFTP,
+ & EAT0P, CORRP
+ COMMON /EMISCR/ EOLD, FITA, DRIFTA, EAT0A, CORRA,
+ & FITP, DRIFTP, EAT0P, CORRP
+C..##IF SAVEFCM
+C..##ENDIF
+C..##IF ACE
+C..##ENDIF
+C..##IF FLUCQ
+C..##ENDIF
+C..##IF ADUMB
+C..##ENDIF
+C..##IF GRID
+C..##ENDIF
+C..##IF FLUCQ
+C..##ENDIF
+C..##IF TSM
+ REAL(KIND=8) TSMTRM(LENENT),TSMTMP(LENENT)
+ COMMON /TSMENG/ TSMTRM,TSMTMP
+C...##IF SAVEFCM
+C...##ENDIF
+C..##ENDIF
+ REAL(KIND=8) EHQBM
+ LOGICAL HQBM
+ COMMON /HQBMVAR/HQBM
+C..##IF SAVEFCM
+C..##ENDIF
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/dimb.fcm'
+C..##IF DIMB (dimbfcm)
+ INTEGER NPARMX,MNBCMP,LENDSK
+ PARAMETER (NPARMX=1000,MNBCMP=300,LENDSK=200000)
+ INTEGER IJXXCM,IJXYCM,IJXZCM,IJYXCM,IJYYCM
+ INTEGER IJYZCM,IJZXCM,IJZYCM,IJZZCM
+ INTEGER IIXXCM,IIXYCM,IIXZCM,IIYYCM
+ INTEGER IIYZCM,IIZZCM
+ INTEGER JJXXCM,JJXYCM,JJXZCM,JJYYCM
+ INTEGER JJYZCM,JJZZCM
+ PARAMETER (IJXXCM=1,IJXYCM=2,IJXZCM=3,IJYXCM=4,IJYYCM=5)
+ PARAMETER (IJYZCM=6,IJZXCM=7,IJZYCM=8,IJZZCM=9)
+ PARAMETER (IIXXCM=1,IIXYCM=2,IIXZCM=3,IIYYCM=4)
+ PARAMETER (IIYZCM=5,IIZZCM=6)
+ PARAMETER (JJXXCM=1,JJXYCM=2,JJXZCM=3,JJYYCM=4)
+ PARAMETER (JJYZCM=5,JJZZCM=6)
+ INTEGER ITER,IPAR1,IPAR2,NFSAV,PINBCM,PJNBCM,PDD1CM,LENCMP
+ LOGICAL QDISK,QDW,QCMPCT
+ COMMON /DIMBI/ ITER,IPAR1,IPAR2,NFSAV,PINBCM,PJNBCM,LENCMP
+ COMMON /DIMBL/ QDISK,QDW,QCMPCT
+C...##IF SAVEFCM
+C...##ENDIF
+C..##ENDIF (dimbfcm)
+C-----------------------------------------------------------------------
+C-----------------------------------------------------------------------
+C:::##INCLUDE '~/charmm_fcm/ctitla.fcm'
+ INTEGER MAXTIT
+ PARAMETER (MAXTIT=32)
+ INTEGER NTITLA,NTITLB
+ CHARACTER(80) TITLEA,TITLEB
+ COMMON /NTITLA/ NTITLA,NTITLB
+ COMMON /CTITLA/ TITLEA(MAXTIT),TITLEB(MAXTIT)
+C..##IF SAVEFCM
+C..##ENDIF
+C-----------------------------------------------------------------------
+C Passed variables
+ INTEGER NAT3,NADD,NPAR,NFREG,NFRET,BLATOM
+ INTEGER ATMPAR(2,*),ATMPAS(2,*),ATMPAD(2,*)
+ INTEGER BNBND(*),BIMAG(*)
+ INTEGER INBCMP(*),JNBCMP(*),PARDIM
+ INTEGER ITMX,IUNMOD,IUNRMD,SAVF
+ INTEGER NBOND,IB(*),JB(*)
+ REAL(KIND=8) X(*),Y(*),Z(*),AMASS(*),DDSCR(*)
+ REAL(KIND=8) DDV(NAT3,*),PARDDV(PARDIM,*),DDM(*),DDS(*)
+ REAL(KIND=8) DDF(*),PARDDF(*),DDEV(*),PARDDE(*)
+ REAL(KIND=8) DD1BLK(*),DD1BLL(*),DD1CMP(*)
+ REAL(KIND=8) TOLDIM,DDVALM
+ REAL(KIND=8) PARFRQ,CUTF1
+ LOGICAL LNOMA,LRAISE,LSCI,LBIG
+C Local variables
+ INTEGER NATOM,NATP,NDIM,I,J,II,OLDFAS,OLDPRN,IUPD
+ INTEGER NPARC,NPARD,NPARS,NFCUT1,NFREG2,NFREG6
+ INTEGER IH1,IH2,IH3,IH4,IH5,IH6,IH7,IH8
+ INTEGER IS1,IS2,IS3,IS4,JSPACE,JSP,DDSS,DD5
+ INTEGER ISTRT,ISTOP,IPA1,IPA2,IRESF
+ INTEGER ATMPAF,INIDS,TRAROT
+ INTEGER SUBLIS,ATMCOR
+ INTEGER NFRRES,DDVBAS
+ INTEGER DDV2,DDVAL
+ INTEGER LENCM,NTR,NFRE,NFC,N1,N2,NFCUT,NSUBP
+ INTEGER SCIFV1,SCIFV2,SCIFV3,SCIFV4,SCIFV6
+ INTEGER DRATQ,ERATQ,E2RATQ,BDRATQ,INRATQ
+ INTEGER I620,I640,I660,I700,I720,I760,I800,I840,I880,I920
+ REAL(KIND=8) CVGMX,TOLER
+ LOGICAL LCARD,LAPPE,LPURG,LWDINI,QCALC,QMASWT,QMIX,QDIAG
+C Begin
+ QCALC=.TRUE.
+ LWDINI=.FALSE.
+ INIDS=0
+ IS3=0
+ IS4=0
+ LPURG=.TRUE.
+ ITER=0
+ NADD=0
+ NFSAV=0
+ TOLER=TENM5
+ QDIAG=.TRUE.
+ CVGMX=HUNDRD
+ QMIX=.FALSE.
+ NATOM=NAT3/3
+ NFREG6=(NFREG-6)/NPAR
+ NFREG2=NFREG/2
+ NFRRES=(NFREG+6)/2
+ IF(NFREG.GT.PARDIM) CALL WRNDIE(-3,'',
+ 1 'NFREG IS LARGER THAN PARDIM*3')
+C
+C ALLOCATE-SPACE-FOR-TRANSROT-VECTORS
+ ASSIGN 801 TO I800
+ GOTO 800
+ 801 CONTINUE
+C ALLOCATE-SPACE-FOR-DIAGONALIZATION
+ ASSIGN 721 TO I720
+ GOTO 720
+ 721 CONTINUE
+C ALLOCATE-SPACE-FOR-REDUCED-BASIS
+ ASSIGN 761 TO I760
+ GOTO 760
+ 761 CONTINUE
+C ALLOCATE-SPACE-FOR-OTHER-ARRAYS
+ ASSIGN 921 TO I920
+ GOTO 920
+ 921 CONTINUE
+C
+C Space allocation for working arrays of EISPACK
+C diagonalization subroutines
+ IF(LSCI) THEN
+C ALLOCATE-SPACE-FOR-LSCI
+ ASSIGN 841 TO I840
+ GOTO 840
+ 841 CONTINUE
+ ELSE
+C ALLOCATE-DUMMY-SPACE-FOR-LSCI
+ ASSIGN 881 TO I880
+ GOTO 880
+ 881 CONTINUE
+ ENDIF
+ QMASWT=(.NOT.LNOMA)
+ IF(.NOT. QDISK) THEN
+ LENCM=INBCMP(NATOM-1)*9+NATOM*6
+ DO I=1,LENCM
+ DD1CMP(I)=0.0
+ ENDDO
+ OLDFAS=LFAST
+ QCMPCT=.TRUE.
+ LFAST = -1
+ CALL ENERGY(X,Y,Z,DX,DY,DZ,BNBND,BIMAG,NAT3,DD1CMP,.TRUE.,1)
+ LFAST=OLDFAS
+ QCMPCT=.FALSE.
+C
+C Mass weight DD1CMP matrix
+C
+ CALL MASSDD(DD1CMP,DDM,INBCMP,JNBCMP,NATOM)
+ ELSE
+ CALL WRNDIE(-3,'','QDISK OPTION NOT SUPPORTED YET')
+C DO I=1,LENDSK
+C DD1CMP(I)=0.0
+C ENDDO
+C OLDFAS=LFAST
+C LFAST = -1
+ ENDIF
+C
+C Fill DDV with six translation-rotation vectors
+C
+ CALL TRROT(X,Y,Z,DDV,NAT3,1,DDM)
+ CALL CPARAY(HEAP(TRAROT),DDV,NAT3,1,6,1)
+ NTR=6
+ OLDPRN=PRNLEV
+ PRNLEV=1
+ CALL ORTHNM(1,6,NTR,HEAP(TRAROT),NAT3,.FALSE.,TOLER) ! { dg-warning "Type mismatch" }
+ PRNLEV=OLDPRN
+ IF(IUNRMD .LT. 0) THEN
+C
+C If no previous basis is read
+C
+ IF(PRNLEV.GE.2) WRITE(OUTU,502) NPAR
+ 502 FORMAT(/' NMDIMB: Calculating initial basis from block ',
+ 1 'diagonals'/' NMDIMB: The number of blocks is ',I5/)
+ NFRET = 6
+ DO I=1,NPAR
+ IS1=ATMPAR(1,I)
+ IS2=ATMPAR(2,I)
+ NDIM=(IS2-IS1+1)*3
+ NFRE=NDIM
+ IF(NFRE.GT.NFREG6) NFRE=NFREG6
+ IF(NFREG6.EQ.0) NFRE=1
+ CALL FILUPT(HEAP(IUPD),NDIM)
+ CALL MAKDDU(DD1BLK,DD1CMP,INBCMP,JNBCMP,HEAP(IUPD),
+ 1 IS1,IS2,NATOM)
+ IF(PRNLEV.GE.9) CALL PRINTE(OUTU,EPROP,ETERM,'VIBR',
+ 1 'ENR',.TRUE.,1,ZERO,ZERO)
+C
+C Generate the lower section of the matrix and diagonalize
+C
+C..##IF EISPACK
+C..##ENDIF
+ IH1=1
+ NATP=NDIM+1
+ IH2=IH1+NATP
+ IH3=IH2+NATP
+ IH4=IH3+NATP
+ IH5=IH4+NATP
+ IH6=IH5+NATP
+ IH7=IH6+NATP
+ IH8=IH7+NATP
+ CALL DIAGQ(NDIM,NFRE,DD1BLK,PARDDV,DDS(IH2),DDS(IH3),
+ 1 DDS(IH4),DDS(IH5),DDS,DDS(IH6),DDS(IH7),DDS(IH8),NADD)
+C..##IF EISPACK
+C..##ENDIF
+C
+C Put the PARDDV vectors into DDV and replace the elements which do
+C not belong to the considered partitioned region by zeros.
+C
+ CALL ADJNME(DDV,PARDDV,NAT3,NDIM,NFRE,NFRET,IS1,IS2)
+ IF(LSCI) THEN
+ DO J=1,NFRE
+ PARDDF(J)=CNVFRQ*SQRT(ABS(PARDDE(J)))
+ IF(PARDDE(J) .LT. 0.0) PARDDF(J)=-PARDDF(J)
+ ENDDO
+ ELSE
+ DO J=1,NFRE
+ PARDDE(J)=DDS(J)
+ PARDDF(J)=CNVFRQ*SQRT(ABS(PARDDE(J)))
+ IF(PARDDE(J) .LT. 0.0) PARDDF(J)=-PARDDF(J)
+ ENDDO
+ ENDIF
+ IF(PRNLEV.GE.2) THEN
+ WRITE(OUTU,512) I
+ WRITE(OUTU,514)
+ WRITE(OUTU,516) (J,PARDDF(J),J=1,NFRE)
+ ENDIF
+ NFRET=NFRET+NFRE
+ IF(NFRET .GE. NFREG) GOTO 10
+ ENDDO
+ 512 FORMAT(/' NMDIMB: Diagonalization of part',I5,' completed')
+ 514 FORMAT(' NMDIMB: Frequencies'/)
+ 516 FORMAT(5(I4,F12.6))
+ 10 CONTINUE
+C
+C Orthonormalize the eigenvectors
+C
+ OLDPRN=PRNLEV
+ PRNLEV=1
+ CALL ORTHNM(1,NFRET,NFRET,DDV,NAT3,LPURG,TOLER) ! { dg-warning "Type mismatch" }
+ PRNLEV=OLDPRN
+C
+C Do reduced basis diagonalization using the DDV vectors
+C and get eigenvectors of zero iteration
+C
+ IF(PRNLEV.GE.2) THEN
+ WRITE(OUTU,521) ITER
+ WRITE(OUTU,523) NFRET
+ ENDIF
+ 521 FORMAT(/' NMDIMB: Iteration number = ',I5)
+ 523 FORMAT(' NMDIMB: Dimension of the reduced basis set = ',I5)
+ IF(LBIG) THEN
+ IF(PRNLEV.GE.2) WRITE(OUTU,585) NFRET,IUNMOD
+ 525 FORMAT(' NMDIMB: ',I5,' basis vectors are saved in unit',I5)
+ REWIND (UNIT=IUNMOD)
+ LCARD=.FALSE.
+ CALL WRTNMD(LCARD,1,NFRET,NAT3,DDV,DDSCR,DDEV,IUNMOD,AMASS)
+ CALL SAVEIT(IUNMOD)
+ ELSE
+ CALL CPARAY(HEAP(DDVBAS),DDV,NAT3,1,NFRET,1)
+ ENDIF
+ CALL RBDG(X,Y,Z,NAT3,NDIM,NFRET,DDV,DDF,DDEV,
+ 1 DDSCR,HEAP(DD5),HEAP(DDSS),HEAP(DDV2),NADD,
+ 2 INBCMP,JNBCMP,HEAP(DDVBAS),DD1CMP,QMIX,0,0,IS3,IS4,
+ 3 CUTF1,NFCUT1,NFREG,HEAP(IUPD),DD1BLL,HEAP(SCIFV1),
+ 4 HEAP(SCIFV2),HEAP(SCIFV3),HEAP(SCIFV4),HEAP(SCIFV6),
+ 5 HEAP(DRATQ),HEAP(ERATQ),HEAP(E2RATQ),
+ 6 HEAP(BDRATQ),HEAP(INRATQ),LSCI,LBIG,IUNMOD)
+C
+C DO-THE-DIAGONALISATIONS-WITH-RESIDUALS
+C
+ ASSIGN 621 TO I620
+ GOTO 620
+ 621 CONTINUE
+C SAVE-MODES
+ ASSIGN 701 TO I700
+ GOTO 700
+ 701 CONTINUE
+ IF(ITER.EQ.ITMX) THEN
+ CALL CLEANHP(NAT3,NFREG,NPARD,NSUBP,PARDIM,DDV2,DDSS,DDVBAS,
+ 1 DDVAL,JSPACE,TRAROT,
+ 2 SCIFV1,SCIFV2,SCIFV3,SCIFV4,SCIFV6,
+ 3 DRATQ,ERATQ,E2RATQ,BDRATQ,INRATQ,IUPD,ATMPAF,
+ 4 ATMCOR,SUBLIS,LSCI,QDW,LBIG)
+ RETURN
+ ENDIF
+ ELSE
+C
+C Read in existing basis
+C
+ IF(PRNLEV.GE.2) THEN
+ WRITE(OUTU,531)
+ 531 FORMAT(/' NMDIMB: Calculations restarted')
+ ENDIF
+C READ-MODES
+ ISTRT=1
+ ISTOP=99999999
+ LCARD=.FALSE.
+ LAPPE=.FALSE.
+ CALL RDNMD(LCARD,NFRET,NFREG,NAT3,NDIM,
+ 1 DDV,DDSCR,DDF,DDEV,
+ 2 IUNRMD,LAPPE,ISTRT,ISTOP)
+ NFRET=NDIM
+ IF(NFRET.GT.NFREG) THEN
+ NFRET=NFREG
+ CALL WRNDIE(-1,'',
+ 1 'Not enough space to hold the basis. Increase NMODes')
+ ENDIF
+C PRINT-MODES
+ IF(PRNLEV.GE.2) THEN
+ WRITE(OUTU,533) NFRET,IUNRMD
+ WRITE(OUTU,514)
+ WRITE(OUTU,516) (J,DDF(J),J=1,NFRET)
+ ENDIF
+ 533 FORMAT(/' NMDIMB: ',I5,' restart modes read from unit ',I5)
+ NFRRES=NFRET
+ ENDIF
+C
+C -------------------------------------------------
+C Here starts the mixed-basis diagonalization part.
+C -------------------------------------------------
+C
+C
+C Check cut-off frequency
+C
+ CALL SELNMD(DDF,NFRET,CUTF1,NFCUT1)
+C TEST-NFCUT1
+ IF(IUNRMD.LT.0) THEN
+ IF(NFCUT1*2-6.GT.NFREG) THEN
+ IF(PRNLEV.GE.2) WRITE(OUTU,537) DDF(NFRRES)
+ NFCUT1=NFRRES
+ CUTF1=DDF(NFRRES)
+ ENDIF
+ ELSE
+ CUTF1=DDF(NFRRES)
+ ENDIF
+ 537 FORMAT(/' NMDIMB: Too many vectors for the given cutoff frequency'
+ 1 /' Cutoff frequency is decreased to',F9.3)
+C
+C Compute the new partioning of the molecule
+C
+ CALL PARTIC(NAT3,NFREG,NFCUT1,NPARMX,NPARC,ATMPAR,NFRRES,
+ 1 PARDIM)
+ NPARS=NPARC
+ DO I=1,NPARC
+ ATMPAS(1,I)=ATMPAR(1,I)
+ ATMPAS(2,I)=ATMPAR(2,I)
+ ENDDO
+ IF(QDW) THEN
+ IF(IPAR1.EQ.0.OR.IPAR2.EQ.0) LWDINI=.TRUE.
+ IF(IPAR1.GE.IPAR2) LWDINI=.TRUE.
+ IF(IABS(IPAR1).GT.NPARC*2) LWDINI=.TRUE.
+ IF(IABS(IPAR2).GT.NPARC*2) LWDINI=.TRUE.
+ IF(ITER.EQ.0) LWDINI=.TRUE.
+ ENDIF
+ ITMX=ITMX+ITER
+ IF(PRNLEV.GE.2) THEN
+ WRITE(OUTU,543) ITER,ITMX
+ IF(QDW) WRITE(OUTU,545) IPAR1,IPAR2
+ ENDIF
+ 543 FORMAT(/' NMDIMB: Previous iteration number = ',I8/
+ 1 ' NMDIMB: Iteration number to reach = ',I8)
+ 545 FORMAT(' NMDIMB: Previous sub-blocks = ',I5,2X,I5)
+C
+ IF(SAVF.LE.0) SAVF=NPARC
+ IF(PRNLEV.GE.2) WRITE(OUTU,547) SAVF
+ 547 FORMAT(' NMDIMB: Eigenvectors will be saved every',I5,
+ 1 ' iterations')
+C
+C If double windowing is defined, the original block sizes are divided
+C in two.
+C
+ IF(QDW) THEN
+ NSUBP=1
+ CALL PARTID(NPARC,ATMPAR,NPARD,ATMPAD,NPARMX)
+ ATMPAF=ALLHP(INTEG4(NPARD*NPARD))
+ ATMCOR=ALLHP(INTEG4(NATOM))
+ DDVAL=ALLHP(IREAL8(NPARD*NPARD))
+ CALL CORARR(ATMPAD,NPARD,HEAP(ATMCOR),NATOM)
+ CALL PARLIS(HEAP(ATMCOR),HEAP(ATMPAF),INBCMP,JNBCMP,NPARD,
+ 2 NSUBP,NATOM,X,Y,Z,NBOND,IB,JB,DD1CMP,HEAP(DDVAL),DDVALM)
+ SUBLIS=ALLHP(INTEG4(NSUBP*2))
+ CALL PARINT(HEAP(ATMPAF),NPARD,HEAP(SUBLIS),NSUBP)
+ CALL INIPAF(HEAP(ATMPAF),NPARD)
+C
+C Find out with which block to continue (double window method only)
+C
+ IPA1=IPAR1
+ IPA2=IPAR2
+ IRESF=0
+ IF(LWDINI) THEN
+ ITER=0
+ LWDINI=.FALSE.
+ GOTO 500
+ ENDIF
+ DO II=1,NSUBP
+ CALL IPART(HEAP(SUBLIS),II,IPAR1,IPAR2,HEAP(ATMPAF),
+ 1 NPARD,QCALC)
+ IF((IPAR1.EQ.IPA1).AND.(IPAR2.EQ.IPA2)) GOTO 500
+ ENDDO
+ ENDIF
+ 500 CONTINUE
+C
+C Main loop.
+C
+ DO WHILE((CVGMX.GT.TOLDIM).AND.(ITER.LT.ITMX))
+ IF(.NOT.QDW) THEN
+ ITER=ITER+1
+ IF(PRNLEV.GE.2) WRITE(OUTU,553) ITER
+ 553 FORMAT(/' NMDIMB: Iteration number = ',I8)
+ IF(INIDS.EQ.0) THEN
+ INIDS=1
+ ELSE
+ INIDS=0
+ ENDIF
+ CALL PARTDS(NAT3,NPARC,ATMPAR,NPARS,ATMPAS,INIDS,NPARMX,
+ 1 DDF,NFREG,CUTF1,PARDIM,NFCUT1)
+C DO-THE-DIAGONALISATIONS
+ ASSIGN 641 to I640
+ GOTO 640
+ 641 CONTINUE
+ QDIAG=.FALSE.
+C DO-THE-DIAGONALISATIONS-WITH-RESIDUALS
+ ASSIGN 622 TO I620
+ GOTO 620
+ 622 CONTINUE
+ QDIAG=.TRUE.
+C SAVE-MODES
+ ASSIGN 702 TO I700
+ GOTO 700
+ 702 CONTINUE
+C
+ ELSE
+ DO II=1,NSUBP
+ CALL IPART(HEAP(SUBLIS),II,IPAR1,IPAR2,HEAP(ATMPAF),
+ 1 NPARD,QCALC)
+ IF(QCALC) THEN
+ IRESF=IRESF+1
+ ITER=ITER+1
+ IF(PRNLEV.GE.2) WRITE(OUTU,553) ITER
+C DO-THE-DWIN-DIAGONALISATIONS
+ ASSIGN 661 TO I660
+ GOTO 660
+ 661 CONTINUE
+ ENDIF
+ IF((IRESF.EQ.SAVF).OR.(ITER.EQ.ITMX)) THEN
+ IRESF=0
+ QDIAG=.FALSE.
+C DO-THE-DIAGONALISATIONS-WITH-RESIDUALS
+ ASSIGN 623 TO I620
+ GOTO 620
+ 623 CONTINUE
+ QDIAG=.TRUE.
+ IF((CVGMX.LE.TOLDIM).OR.(ITER.EQ.ITMX)) GOTO 600
+C SAVE-MODES
+ ASSIGN 703 TO I700
+ GOTO 700
+ 703 CONTINUE
+ ENDIF
+ ENDDO
+ ENDIF
+ ENDDO
+ 600 CONTINUE
+C
+C SAVE-MODES
+ ASSIGN 704 TO I700
+ GOTO 700
+ 704 CONTINUE
+ CALL CLEANHP(NAT3,NFREG,NPARD,NSUBP,PARDIM,DDV2,DDSS,DDVBAS,
+ 1 DDVAL,JSPACE,TRAROT,
+ 2 SCIFV1,SCIFV2,SCIFV3,SCIFV4,SCIFV6,
+ 3 DRATQ,ERATQ,E2RATQ,BDRATQ,INRATQ,IUPD,ATMPAF,
+ 4 ATMCOR,SUBLIS,LSCI,QDW,LBIG)
+ RETURN
+C-----------------------------------------------------------------------
+C INTERNAL PROCEDURES
+C-----------------------------------------------------------------------
+C TO DO-THE-DIAGONALISATIONS-WITH-RESIDUALS
+ 620 CONTINUE
+ IF(IUNRMD.LT.0) THEN
+ CALL SELNMD(DDF,NFRET,CUTF1,NFC)
+ N1=NFCUT1
+ N2=(NFRET+6)/2
+ NFCUT=MAX(N1,N2)
+ IF(NFCUT*2-6 .GT. NFREG) THEN
+ NFCUT=(NFREG+6)/2
+ CUTF1=DDF(NFCUT)
+ IF(PRNLEV.GE.2) THEN
+ WRITE(OUTU,562) ITER
+ WRITE(OUTU,564) CUTF1
+ ENDIF
+ ENDIF
+ ELSE
+ NFCUT=NFRET
+ NFC=NFRET
+ ENDIF
+ 562 FORMAT(/' NMDIMB: Not enough space to hold the residual vectors'/
+ 1 ' into DDV array during iteration ',I5)
+ 564 FORMAT(' Cutoff frequency is changed to ',F9.3)
+C
+C do reduced diagonalization with preceding eigenvectors plus
+C residual vectors
+C
+ ISTRT=1
+ ISTOP=NFCUT
+ CALL CLETR(DDV,HEAP(TRAROT),NAT3,ISTRT,ISTOP,NFCUT,DDEV,DDF)
+ CALL RNMTST(DDV,HEAP(DDVBAS),NAT3,DDSCR,DD1CMP,INBCMP,JNBCMP,
+ 2 7,NFCUT,CVGMX,NFCUT,NFC,QDIAG,LBIG,IUNMOD)
+ NFSAV=NFCUT
+ IF(QDIAG) THEN
+ NFRET=NFCUT*2-6
+ IF(PRNLEV.GE.2) WRITE(OUTU,566) NFRET
+ 566 FORMAT(/' NMDIMB: Diagonalization with residual vectors. '/
+ 1 ' Dimension of the reduced basis set'/
+ 2 ' before orthonormalization = ',I5)
+ NFCUT=NFRET
+ OLDPRN=PRNLEV
+ PRNLEV=1
+ CALL ORTHNM(1,NFRET,NFCUT,DDV,NAT3,LPURG,TOLER)
+ PRNLEV=OLDPRN
+ NFRET=NFCUT
+ IF(PRNLEV.GE.2) WRITE(OUTU,568) NFRET
+ 568 FORMAT(' after orthonormalization = ',I5)
+ IF(LBIG) THEN
+ IF(PRNLEV.GE.2) WRITE(OUTU,570) NFCUT,IUNMOD
+ 570 FORMAT(' NMDIMB: ',I5,' basis vectors are saved in unit',I5)
+ REWIND (UNIT=IUNMOD)
+ LCARD=.FALSE.
+ CALL WRTNMD(LCARD,1,NFCUT,NAT3,DDV,DDSCR,DDEV,IUNMOD,AMASS)
+ CALL SAVEIT(IUNMOD)
+ ELSE
+ CALL CPARAY(HEAP(DDVBAS),DDV,NAT3,1,NFCUT,1)
+ ENDIF
+ QMIX=.FALSE.
+ CALL RBDG(X,Y,Z,NAT3,NDIM,NFRET,DDV,DDF,DDEV,
+ 1 DDSCR,HEAP(DD5),HEAP(DDSS),HEAP(DDV2),NADD,
+ 2 INBCMP,JNBCMP,HEAP(DDVBAS),DD1CMP,QMIX,0,0,IS3,IS4,
+ 3 CUTF1,NFCUT1,NFREG,HEAP(IUPD),DD1BLL,HEAP(SCIFV1),
+ 4 HEAP(SCIFV2),HEAP(SCIFV3),HEAP(SCIFV4),HEAP(SCIFV6),
+ 5 HEAP(DRATQ),HEAP(ERATQ),HEAP(E2RATQ),
+ 6 HEAP(BDRATQ),HEAP(INRATQ),LSCI,LBIG,IUNMOD)
+ CALL SELNMD(DDF,NFRET,CUTF1,NFCUT1)
+ ENDIF
+ GOTO I620
+C
+C-----------------------------------------------------------------------
+C TO DO-THE-DIAGONALISATIONS
+ 640 CONTINUE
+ DO I=1,NPARC
+ NFCUT1=NFRRES
+ IS1=ATMPAR(1,I)
+ IS2=ATMPAR(2,I)
+ NDIM=(IS2-IS1+1)*3
+ IF(PRNLEV.GE.2) WRITE(OUTU,573) I,IS1,IS2
+ 573 FORMAT(/' NMDIMB: Mixed diagonalization, part ',I5/
+ 1 ' NMDIMB: Block limits: ',I5,2X,I5)
+ IF(NDIM+NFCUT1.GT.PARDIM) CALL WRNDIE(-3,'',
+ 1 'Error in dimension of block')
+ NFRET=NFCUT1
+ IF(NFRET.GT.NFREG) NFRET=NFREG
+ CALL CLETR(DDV,HEAP(TRAROT),NAT3,1,NFCUT1,NFCUT,DDEV,DDF)
+ NFCUT1=NFCUT
+ CALL ADZER(DDV,1,NFCUT1,NAT3,IS1,IS2)
+ NFSAV=NFCUT1
+ OLDPRN=PRNLEV
+ PRNLEV=1
+ CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER)
+ PRNLEV=OLDPRN
+ CALL CPARAY(HEAP(DDVBAS),DDV,NAT3,1,NFCUT,1)
+ NFRET=NDIM+NFCUT
+ QMIX=.TRUE.
+ CALL RBDG(X,Y,Z,NAT3,NDIM,NFRET,DDV,DDF,DDEV,
+ 1 DDSCR,HEAP(DD5),HEAP(DDSS),HEAP(DDV2),NADD,
+ 2 INBCMP,JNBCMP,HEAP(DDVBAS),DD1CMP,QMIX,IS1,IS2,IS3,IS4,
+ 3 CUTF1,NFCUT,NFREG,HEAP(IUPD),DD1BLL,HEAP(SCIFV1),
+ 4 HEAP(SCIFV2),HEAP(SCIFV3),HEAP(SCIFV4),HEAP(SCIFV6),
+ 5 HEAP(DRATQ),HEAP(ERATQ),HEAP(E2RATQ),
+ 6 HEAP(BDRATQ),HEAP(INRATQ),LSCI,LBIG,IUNMOD)
+ QMIX=.FALSE.
+ IF(NFCUT.GT.NFRRES) NFCUT=NFRRES
+ NFCUT1=NFCUT
+ NFRET=NFCUT
+ ENDDO
+ GOTO I640
+C
+C-----------------------------------------------------------------------
+C TO DO-THE-DWIN-DIAGONALISATIONS
+ 660 CONTINUE
+C
+C Store the DDV vectors into DDVBAS
+C
+ NFCUT1=NFRRES
+ IS1=ATMPAD(1,IPAR1)
+ IS2=ATMPAD(2,IPAR1)
+ IS3=ATMPAD(1,IPAR2)
+ IS4=ATMPAD(2,IPAR2)
+ NDIM=(IS2-IS1+IS4-IS3+2)*3
+ IF(PRNLEV.GE.2) WRITE(OUTU,577) IPAR1,IPAR2,IS1,IS2,IS3,IS4
+ 577 FORMAT(/' NMDIMB: Mixed double window diagonalization, parts ',
+ 1 2I5/
+ 2 ' NMDIMB: Block limits: ',I5,2X,I5,4X,I5,2X,I5)
+ IF(NDIM+NFCUT1.GT.PARDIM) CALL WRNDIE(-3,'',
+ 1 'Error in dimension of block')
+ NFRET=NFCUT1
+ IF(NFRET.GT.NFREG) NFRET=NFREG
+C
+C Prepare the DDV vectors consisting of 6 translations-rotations
+C + eigenvectors from 7 to NFCUT1 + cartesian displacements vectors
+C spanning the atoms from IS1 to IS2
+C
+ CALL CLETR(DDV,HEAP(TRAROT),NAT3,1,NFCUT1,NFCUT,DDEV,DDF)
+ NFCUT1=NFCUT
+ NFSAV=NFCUT1
+ CALL ADZERD(DDV,1,NFCUT1,NAT3,IS1,IS2,IS3,IS4)
+ OLDPRN=PRNLEV
+ PRNLEV=1
+ CALL ORTHNM(1,NFCUT1,NFCUT,DDV,NAT3,LPURG,TOLER)
+ PRNLEV=OLDPRN
+ CALL CPARAY(HEAP(DDVBAS),DDV,NAT3,1,NFCUT,1)
+C
+ NFRET=NDIM+NFCUT
+ QMIX=.TRUE.
+ CALL RBDG(X,Y,Z,NAT3,NDIM,NFRET,DDV,DDF,DDEV,
+ 1 DDSCR,HEAP(DD5),HEAP(DDSS),HEAP(DDV2),NADD,
+ 2 INBCMP,JNBCMP,HEAP(DDVBAS),DD1CMP,QMIX,IS1,IS2,IS3,IS4,
+ 3 CUTF1,NFCUT,NFREG,HEAP(IUPD),DD1BLL,HEAP(SCIFV1),
+ 4 HEAP(SCIFV2),HEAP(SCIFV3),HEAP(SCIFV4),HEAP(SCIFV6),
+ 5 HEAP(DRATQ),HEAP(ERATQ),HEAP(E2RATQ),
+ 6 HEAP(BDRATQ),HEAP(INRATQ),LSCI,LBIG,IUNMOD)
+ QMIX=.FALSE.
+C
+ IF(NFCUT.GT.NFRRES) NFCUT=NFRRES
+ NFCUT1=NFCUT
+ NFRET=NFCUT
+ GOTO I660
+C
+C-----------------------------------------------------------------------
+C TO SAVE-MODES
+ 700 CONTINUE
+ IF(PRNLEV.GE.2) WRITE(OUTU,583) IUNMOD
+ 583 FORMAT(/' NMDIMB: Saving the eigenvalues and eigenvectors to unit'
+ 1 ,I4)
+ REWIND (UNIT=IUNMOD)
+ ISTRT=1
+ ISTOP=NFSAV
+ LCARD=.FALSE.
+ IF(PRNLEV.GE.2) WRITE(OUTU,585) NFSAV,IUNMOD
+ 585 FORMAT(' NMDIMB: ',I5,' modes are saved in unit',I5)
+ CALL WRTNMD(LCARD,ISTRT,ISTOP,NAT3,DDV,DDSCR,DDEV,IUNMOD,
+ 1 AMASS)
+ CALL SAVEIT(IUNMOD)
+ GOTO I700
+C
+C-----------------------------------------------------------------------
+C TO ALLOCATE-SPACE-FOR-DIAGONALIZATION
+ 720 CONTINUE
+ DDV2=ALLHP(IREAL8((PARDIM+3)*(PARDIM+3)))
+ JSPACE=IREAL8((PARDIM+4))*8
+ JSP=IREAL8(((PARDIM+3)*(PARDIM+4))/2)
+ JSPACE=JSPACE+JSP
+ DDSS=ALLHP(JSPACE)
+ DD5=DDSS+JSPACE-JSP
+ GOTO I720
+C
+C-----------------------------------------------------------------------
+C TO ALLOCATE-SPACE-FOR-REDUCED-BASIS
+ 760 CONTINUE
+ IF(LBIG) THEN
+ DDVBAS=ALLHP(IREAL8(NAT3))
+ ELSE
+ DDVBAS=ALLHP(IREAL8(NFREG*NAT3))
+ ENDIF
+ GOTO I760
+C
+C-----------------------------------------------------------------------
+C TO ALLOCATE-SPACE-FOR-TRANSROT-VECTORS
+ 800 CONTINUE
+ TRAROT=ALLHP(IREAL8(6*NAT3))
+ GOTO I800
+C
+C-----------------------------------------------------------------------
+C TO ALLOCATE-SPACE-FOR-LSCI
+ 840 CONTINUE
+ SCIFV1=ALLHP(IREAL8(PARDIM+3))
+ SCIFV2=ALLHP(IREAL8(PARDIM+3))
+ SCIFV3=ALLHP(IREAL8(PARDIM+3))
+ SCIFV4=ALLHP(IREAL8(PARDIM+3))
+ SCIFV6=ALLHP(IREAL8(PARDIM+3))
+ DRATQ=ALLHP(IREAL8(PARDIM+3))
+ ERATQ=ALLHP(IREAL8(PARDIM+3))
+ E2RATQ=ALLHP(IREAL8(PARDIM+3))
+ BDRATQ=ALLHP(IREAL8(PARDIM+3))
+ INRATQ=ALLHP(INTEG4(PARDIM+3))
+ GOTO I840
+C
+C-----------------------------------------------------------------------
+C TO ALLOCATE-DUMMY-SPACE-FOR-LSCI
+ 880 CONTINUE
+ SCIFV1=ALLHP(IREAL8(2))
+ SCIFV2=ALLHP(IREAL8(2))
+ SCIFV3=ALLHP(IREAL8(2))
+ SCIFV4=ALLHP(IREAL8(2))
+ SCIFV6=ALLHP(IREAL8(2))
+ DRATQ=ALLHP(IREAL8(2))
+ ERATQ=ALLHP(IREAL8(2))
+ E2RATQ=ALLHP(IREAL8(2))
+ BDRATQ=ALLHP(IREAL8(2))
+ INRATQ=ALLHP(INTEG4(2))
+ GOTO I880
+C
+C-----------------------------------------------------------------------
+C TO ALLOCATE-SPACE-FOR-OTHER-ARRAYS
+ 920 CONTINUE
+ IUPD=ALLHP(INTEG4(PARDIM+3))
+ GOTO I920
+C.##ELSE
+C.##ENDIF
+ END
Index: Fortran/gfortran/regression/g77/20010610.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20010610.f
@@ -0,0 +1,5 @@
+c { dg-do run }
+ DO I = 0, 255
+ IF (ICHAR(CHAR(I)) .NE. I) STOP 1
+ ENDDO
+ END
Index: Fortran/gfortran/regression/g77/20020307-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20020307-1.f
@@ -0,0 +1,23 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+ SUBROUTINE SWEEP
+ PARAMETER(MAXDIM=4,MAXVEC=4**3*8,MAXT=20)
+ REAL(KIND=8) B,W1,W2,BNORM,BINV,WT,W0,C1,C2,R1,R2
+ DIMENSION B(MAXVEC,0:3),W1(MAXVEC,0:3),W2(MAXVEC,0:3)
+ DIMENSION BNORM(MAXVEC),BINV(MAXVEC),WT(MAXVEC),W0(MAXVEC)
+ DIMENSION C1(MAXVEC),C2(MAXVEC),R1(MAXVEC),R2(MAXVEC)
+ DO 200 ILAT=1,2**IDIM
+ DO 200 I1=1,IDIM
+ DO 220 I2=1,IDIM
+ CALL INTACT(ILAT,I1,I1,W1)
+220 CONTINUE
+ DO 310 IATT=1,IDIM
+ DO 311 I=1,100
+ WT(I)=ONE + C1(I)*LOG(EPS+R1(I))
+ IF( R2(I)**2 .LE. (ONE-WT(I)**2) )THEN
+ W0(I)=WT(I)
+ ENDIF
+311 CONTINUE
+310 CONTINUE
+200 CONTINUE
+ END
Index: Fortran/gfortran/regression/g77/20030326-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/20030326-1.f
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options -pedantic }
+! PR fortran/9793
+! larson@w6yx.stanford.edu
+!
+! For gfortran, see PR 13490
+!
+ integer c
+ c = -2147483648_4 / (-1) ! { dg-error "too big for its kind" }
+ end
Index: Fortran/gfortran/regression/g77/6177.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/6177.f
@@ -0,0 +1,15 @@
+c { dg-do run }
+ program pr6177
+C
+C Test case for PR optimization/6177.
+C This bug (an ICE) originally showed up in file cblat2.f from LAPACK.
+C
+ complex x
+ complex w(1)
+ intrinsic conjg
+ x = (2.0d0, 1.0d0)
+ w(1) = x
+ x = conjg(x)
+ w(1) = conjg(w(1))
+ if (abs(x-w(1)) .gt. 1.0e-5) STOP 1
+ end
Index: Fortran/gfortran/regression/g77/7388.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/7388.f
@@ -0,0 +1,12 @@
+C { dg-do run }
+C { dg-options "-fbounds-check" }
+ character*25 buff(0:10)
+ character*80 line
+ integer i, m1, m2
+ i = 1
+ m1 = 1
+ m2 = 7
+ buff(i) = 'tcase0a'
+ write(line,*) buff(i)(m1:m2)
+ if (line .ne. ' tcase0a') STOP 1
+ end
Index: Fortran/gfortran/regression/g77/8485.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/8485.f
@@ -0,0 +1,9 @@
+c { dg-do compile }
+C Extracted from PR fortran/8485
+ PARAMETER (PPMULT = 1.0E5)
+ INTEGER(kind=8) NWRONG
+ PARAMETER (NWRONG = 8)
+ PARAMETER (DDMULT = PPMULT * NWRONG)
+ PRINT 10, DDMULT
+10 FORMAT (F10.3)
+ END
Index: Fortran/gfortran/regression/g77/9263.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/9263.f
@@ -0,0 +1,11 @@
+C { dg-do compile }
+ PARAMETER (Q=1)
+ PARAMETER (P=10)
+ INTEGER C(10),D(10),E(10),F(10)
+C TERMINAL NOT INTEGER
+ DATA (C(I),I=1,P) /10*10/ ! { dg-error "End expression in DO loop" }
+C START NOT INTEGER
+ DATA (D(I),I=Q,10) /10*10/ ! { dg-error "Start expression in DO loop" }
+C INCREMENT NOT INTEGER
+ DATA (E(I),I=1,10,Q) /10*10/ ! { dg-error "Step expression in DO loop" }
+ END
Index: Fortran/gfortran/regression/g77/947.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/947.f
@@ -0,0 +1,13 @@
+c { dg-do run }
+ DIMENSION A(-5:5)
+ INTEGER(kind=1) IM5, IZ, IP5
+ INTEGER(kind=2) IM1, IP1
+ PARAMETER (IM5=-5, IM1=-1, IZ=0, IP1=1, IP5=5)
+ DATA A(IM5) /-5./, A(IM1) /-1./
+ DATA A(IZ) /0./
+ DATA A(IP5) /+5./, A(IP1) /+1./
+ IF (A(IM5) .NE. -5. .OR. A(IM1) .NE. -1. .OR.
+ , A(IZ) .NE. 0. .OR.
+ , A(IP5) .NE. +5. .OR. A(IP1) .NE. +1. )
+ , STOP 1
+ END
Index: Fortran/gfortran/regression/g77/960317-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/960317-1.f
@@ -0,0 +1,104 @@
+c { dg-do compile }
+* Date: Sat, 16 Mar 1996 19:58:37 -0500 (EST)
+* From: Kate Hedstrom
+* To: burley@gnu.ai.mit.edu
+* Subject: g77 bug in assign
+*
+* I found some files in the NCAR graphics source code which used to
+* compile with g77 and now don't. All contain the following combination
+* of "save" and "assign". It fails on a Sun running SunOS 4.1.3 and a
+* Sun running SunOS 5.5 (slightly older g77), but compiles on an
+* IBM/RS6000:
+*
+C
+ SUBROUTINE QUICK
+ SAVE
+C
+ ASSIGN 101 TO JUMP ! { dg-warning "Deleted feature: ASSIGN" }
+ 101 Continue
+C
+ RETURN
+ END
+*
+* Everything else in the NCAR distribution compiled, including quite a
+* few C routines.
+*
+* Kate
+*
+*
+* nemo% g77 -v -c quick.f
+* gcc -v -c -xf77 quick.f
+* Reading specs from /usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.7.2/specs
+* gcc version 2.7.2
+* /usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.7.2/f771 quick.f -fset-g77-defaults -quiet -dumpbase quick.f -version -fversion -o /usr/tmp/cca24166.s
+* GNU F77 version 2.7.2 (sparc) compiled by GNU C version 2.7.1.
+* GNU Fortran Front End version 0.5.18-960314 compiled: Mar 16 1996 14:28:11
+* gcc: Internal compiler error: program f771 got fatal signal 11
+*
+*
+* nemo% gdb /usr/local/lib/gcc-lib/*/*/f771 core
+* GDB is free software and you are welcome to distribute copies of it
+* under certain conditions; type "show copying" to see the conditions.
+* There is absolutely no warranty for GDB; type "show warranty" for details.
+* GDB 4.14 (sparc-sun-sunos4.1.3),
+* Copyright 1995 Free Software Foundation, Inc...
+* Core was generated by `f771'.
+* Program terminated with signal 11, Segmentation fault.
+* Couldn't read input and local registers from core file
+* find_solib: Can't read pathname for load map: I/O error
+*
+* Couldn't read input and local registers from core file
+* #0 0x21aa4 in ffecom_sym_transform_assign_ (s=???) at f/com.c:7881
+* 7881 if ((ffesymbol_save (s) || ffe_is_saveall ())
+* (gdb) where
+* #0 0x21aa4 in ffecom_sym_transform_assign_ (s=???) at f/com.c:7881
+* Error accessing memory address 0xefffefcc: Invalid argument.
+* (gdb)
+*
+*
+* ahab% g77 -v -c quick.f
+* gcc -v -c -xf77 quick.f
+* Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/specs
+* gcc version 2.7.2
+* /usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/f771 quick.f -quiet -dumpbase quick.f -version -fversion -o /var/tmp/cca003D2.s
+* GNU F77 version 2.7.2 (sparc) compiled by GNU C version 2.7.2.
+* GNU Fortran Front End version 0.5.18-960304 compiled: Mar 5 1996 16:12:46
+* gcc: Internal compiler error: program f771 got fatal signal 11
+*
+*
+* ahab% !gdb
+* gdb /usr/local/lib/gcc-lib/*/*/f771 core
+* GDB is free software and you are welcome to distribute copies of it
+* under certain conditions; type "show copying" to see the conditions.
+* There is absolutely no warranty for GDB; type "show warranty" for details.
+* GDB 4.15.1 (sparc-sun-solaris2.4),
+* Copyright 1995 Free Software Foundation, Inc...
+* Core was generated by
+* `/usr/local/lib/gcc-lib/sparc-sun-solaris2.5/2.7.2/f771 quick.f -quiet -dumpbase'.
+* Program terminated with signal 11, Segmentation fault.
+* Reading symbols from /usr/lib/libc.so.1...done.
+* Reading symbols from /usr/lib/libdl.so.1...done.
+* #0 0x43e04 in ffecom_sym_transform_assign_ (s=0x3a22f8) at f/com.c:7963
+* Source file is more recent than executable.
+* 7963 assert (st != NULL);
+* (gdb) where
+* #0 0x43e04 in ffecom_sym_transform_assign_ (s=0x3a22f8) at f/com.c:7963
+* #1 0x38044 in ffecom_expr_ (expr=0x3a23c0, dest_tree=0x0, dest=0x0, dest_used=0x0, assignp=true) at f/com.c:2100
+* #2 0x489c8 in ffecom_expr_assign_w (expr=0x3a23c0) at f/com.c:10238
+* #3 0xe9228 in ffeste_R838 (label=0x3a1ba8, target=0x3a23c0) at f/ste.c:2769
+* #4 0xdae60 in ffestd_stmt_pass_ () at f/std.c:840
+* #5 0xdc090 in ffestd_exec_end () at f/std.c:1405
+* #6 0xcb534 in ffestc_shriek_subroutine_ (ok=true) at f/stc.c:4849
+* #7 0xd8f00 in ffestc_R1225 (name=0x0) at f/stc.c:12307
+* #8 0xcc808 in ffestc_end () at f/stc.c:5572
+* #9 0x9fa84 in ffestb_end3_ (t=0x3a19c8) at f/stb.c:3216
+* #10 0x9f30c in ffestb_end (t=0x3a19c8) at f/stb.c:2995
+* #11 0x98414 in ffesta_save_ (t=0x3a19c8) at f/sta.c:453
+* #12 0x997ec in ffesta_second_ (t=0x3a19c8) at f/sta.c:1178
+* #13 0x8ed84 in ffelex_send_token_ () at f/lex.c:1614
+* #14 0x8cab8 in ffelex_finish_statement_ () at f/lex.c:946
+* #15 0x91684 in ffelex_file_fixed (wf=0x397780, f=0x37a560) at f/lex.c:2946
+* #16 0x107a94 in ffe_file (wf=0x397780, f=0x37a560) at f/top.c:456
+* #17 0x96218 in yyparse () at f/parse.c:77
+* #18 0x10beac in compile_file (name=0xdffffaf7 "quick.f") at toplev.c:2239
+* #19 0x110dc0 in main (argc=9, argv=0xdffff994, envp=0xdffff9bc) at toplev.c:3927
Index: Fortran/gfortran/regression/g77/970125-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/970125-0.f
@@ -0,0 +1,44 @@
+c { dg-do compile }
+c
+c { dg-additional-options "-w" }
+c
+C JCB comments:
+C g77 doesn't accept the added line "integer(kind=7) ..." --
+C it crashes!
+C
+C It's questionable that g77 DTRT with regarding to passing
+C %LOC() as an argument (thus by reference) and the new global
+C analysis. I need to look into that further; my feeling is that
+C passing %LOC() as an argument should be treated like passing an
+C INTEGER(KIND=7) by reference, and no more specially than that
+C (and that INTEGER(KIND=7) should be permitted as equivalent to
+C INTEGER(KIND=1), INTEGER(KIND=2), or whatever, depending on the
+C system's pointer size).
+C
+C The back end *still* has a bug here, which should be fixed,
+C because, currently, what g77 is passing to it is, IMO, correct.
+
+C No options:
+C ../../egcs/gcc/f/info.c:259: failed assertion `ffeinfo_types_[basictype][kindtype] != NULL'
+C -fno-globals -O:
+C ../../egcs/gcc/expr.c:7291: Internal compiler error in function expand_expr
+
+c Frontend bug fixed by JCB 1998-06-01 com.c &c changes.
+
+ integer i4
+ integer(kind=8) i8
+ integer(kind=8) max4
+ data max4/2147483647/
+ i4 = %loc(i4)
+ i8 = %loc(i8)
+ print *, max4
+ print *, i4, %loc(i4)
+ print *, i8, %loc(i8)
+ call foo(i4, %loc(i4), i8, %loc(i8)) ! { dg-error "Type mismatch in argument 'i8a' at .1.; passed INTEGER.8. to INTEGER.4." }
+ end
+ subroutine foo(i4, i4a, i8, i8a)
+ integer(kind=7) i4a, i8a ! { dg-error "Kind 7 not supported for type INTEGER" }
+ integer(kind=8) i8
+ print *, i4, i4a
+ print *, i8, i8a
+ end
Index: Fortran/gfortran/regression/g77/970625-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/970625-2.f
@@ -0,0 +1,84 @@
+* Date: Wed, 25 Jun 1997 12:48:26 +0200 (MET DST)
+* MIME-Version: 1.0
+* From: R.Hooft@EuroMail.com (Rob Hooft)
+* To: g77-alpha@gnu.ai.mit.edu
+* Subject: Re: testing 970624.
+* In-Reply-To: <199706251027.GAA07892@churchy.gnu.ai.mit.edu>
+* References: <199706251018.MAA21538@nu>
+* <199706251027.GAA07892@churchy.gnu.ai.mit.edu>
+* X-Mailer: VM 6.30 under Emacs 19.34.1
+* Content-Type: text/plain; charset=US-ASCII
+*
+* >>>>> "CB" == Craig Burley writes:
+*
+* CB> but OTOH I'd like to see more problems like this on other
+* CB> applications, and especially other systems
+*
+* How about this one: An application that prints "112." on all
+* compilers/platforms I have tested, except with the new g77 on ALPHA (I
+* don't have the new g77 on any other platform here to test)?
+*
+* Application Appended. Source code courtesy of my boss.....
+* Disclaimer: I do not know the right answer, or even whether there is a
+* single right answer.....
+*
+* Regards,
+* --
+* ===== R.Hooft@EuroMail.com http://www.Sander.EMBL-Heidelberg.DE/rob/ ==
+* ==== In need of protein modeling? http://www.Sander.EMBL-Heidelberg.DE/whatif/
+* Validation of protein structures? http://biotech.EMBL-Heidelberg.DE:8400/ ====
+* == PGPid 0xFA19277D == Use Linux! Free Software Rules The World! =============
+*
+* nu[152]for% cat humor.f
+ PROGRAM SUBROUTINE
+ LOGICAL ELSE IF
+ INTEGER REAL, GO TO PROGRAM, WHILE, THEN, END DO
+ REAL FORMAT(2)
+ DATA IF,REAL,END DO,WHILE,FORMAT(2),I2/2,6,7,1,112.,1/
+ DO THEN=1, END DO, WHILE
+ CALL = END DO - IF
+ PROGRAM = THEN - IF
+ ELSE IF = THEN .GT. IF
+ IF (THEN.GT.REAL) THEN
+ CALL FUNCTION PROGRAM (ELSE IF, GO TO PROGRAM, THEN) ! { dg-error "Type mismatch in argument" }
+ ELSE IF (ELSE IF) THEN
+ REAL = THEN + END DO
+ END IF
+ END DO
+ 10 FORMAT(I2/I2) = WHILE*REAL*THEN
+ IF (FORMAT(I2) .NE. FORMAT(I2+I2)) STOP 1
+ END ! DO
+ SUBROUTINE FUNCTION PROGRAM (REAL,INTEGER, LOGICAL)
+ LOGICAL REAL
+ REAL LOGICAL
+ INTEGER INTEGER, STOP, RETURN, GO TO
+ ASSIGN 9 TO STOP ! { dg-warning "ASSIGN" }
+ ASSIGN = 9 + LOGICAL
+ ASSIGN 7 TO RETURN ! { dg-warning "ASSIGN" }
+ ASSIGN 9 TO GO TO ! { dg-warning "ASSIGN" }
+ GO TO = 5
+ STOP = 8
+ IF (.NOT.REAL) GOTO STOP ! { dg-warning "Assigned GOTO" }
+ IF (LOGICAL.GT.INTEGER) THEN
+ IF = LOGICAL +5
+ IF (LOGICAL.EQ.5) ASSIGN 5 TO IF ! { dg-warning "ASSIGN" }
+ INTEGER=IF
+ ELSE
+ IF (ASSIGN.GT.STOP) ASSIGN 9 TO GOTO ! { dg-warning "ASSIGN" }
+ ELSE = GO TO
+ END IF = ELSE + GO TO
+ IF (.NOT.REAL.AND.GOTO.GT.ELSE) GOTO RETURN ! { dg-warning "Assigned GOTO" }
+ END IF
+ 5 CONTINUE
+ 7 LOGICAL=LOGICAL+STOP
+ 9 RETURN
+ END ! IF
+* nu[153]for% f77 humor.f
+* nu[154]for% ./a.out
+* 112.0000
+* nu[155]for% f90 humor.f
+* nu[156]for% ./a.out
+* 112.0000
+* nu[157]for% g77 humor.f
+* nu[158]for% ./a.out
+* 40.
Index: Fortran/gfortran/regression/g77/970816-3.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/970816-3.f
@@ -0,0 +1,21 @@
+c { dg-do run }
+* Date: Wed, 13 Aug 1997 15:34:23 +0200 (METDST)
+* From: Claus Denk
+* To: g77-alpha@gnu.ai.mit.edu
+* Subject: 970811 report - segfault bug on alpha still there
+*[...]
+* Now, the bug that I reported some weeks ago is still there, I'll post
+* the test program again:
+*
+ PROGRAM TEST
+C a bug in g77-0.5.21 - alpha. Works with NSTART=0 and segfaults with
+C NSTART=1 on the second write.
+ PARAMETER (NSTART=1,NADD=NSTART+1)
+ REAL AB(NSTART:NSTART)
+ AB(NSTART)=1.0
+ I=1
+ J=2
+ IND=I-J+NADD
+ write(*,*) AB(IND)
+ write(*,*) AB(I-J+NADD)
+ END
Index: Fortran/gfortran/regression/g77/970915-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/970915-0.f
@@ -0,0 +1,21 @@
+c { dg-do compile }
+* fixed by patch to safe_from_p to avoid visiting any SAVE_EXPR
+* node twice in a given top-level call to it.
+* (JCB com.c patch of 1998-06-04.)
+
+ SUBROUTINE TSTSIG11
+ IMPLICIT COMPLEX (A-Z)
+ EXTERNAL gzi1,gzi2
+ branch3 = sw2 / cw
+ . * ( rdw * (epsh*gzi1(A,B)-gzi2(A,B))
+ . + rdw * (epsh*gzi1(A,B)-gzi2(A,B)) )
+ . + (-1./2. + 2.*sw2/3.) / (sw*cw)
+ . * rdw * (epsh*gzi1(A,B)-gzi2(A,B)
+ . + rdw * (epsh*gzi1(A,B)-gzi2(A,B))
+ . + rdw * (epsh*gzi1(A,B)-gzi2(A,B)) )
+ . * rup * (epsh*gzi1(A,B)-gzi2(A,B)
+ . + rup * (epsh*gzi1(A,B)-gzi2(A,B)) )
+ . * 4.*(3.-tw**2) * gzi2(A,B)
+ . + ((1.+2./tauw)*tw**2-(5.+2./tauw))* gzi1(A,B)
+ RETURN
+ END
Index: Fortran/gfortran/regression/g77/971102-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/971102-1.f
@@ -0,0 +1,12 @@
+c { dg-do run }
+ i=3
+ j=0
+ do i=i,5
+ j = j+i
+ end do
+ do i=3,i
+ j = j+i
+ end do
+ if (i.ne.7) STOP 1
+ print *, i,j
+ end
Index: Fortran/gfortran/regression/g77/980310-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980310-1.f
@@ -0,0 +1,29 @@
+c { dg-do compile }
+C Causes internal compiler error on egcs 1.0.1 on i586-pc-sco3.2v5.0.4
+C To: egcs-bugs@cygnus.com
+C Subject: backend case range problem/fix
+C From: Dave Love
+C Date: 02 Dec 1997 18:11:35 +0000
+C Message-ID:
+C
+C The following Fortran test case aborts the compiler because
+C tree_int_cst_lt dereferences a null tree; this is a regression from
+C gcc 2.7.
+
+ INTEGER N
+ READ(*,*) N
+ SELECT CASE (N)
+ CASE (1:)
+ WRITE(*,*) 'case 1'
+ CASE (0)
+ WRITE(*,*) 'case 0'
+ END SELECT
+ END
+
+C The relevant change to cure this is:
+C
+C Thu Dec 4 06:34:40 1997 Richard Kenner
+C
+C * stmt.c (pushcase_range): Clean up handling of "infinite" values.
+C
+
Index: Fortran/gfortran/regression/g77/980310-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980310-2.f
@@ -0,0 +1,44 @@
+c { dg-do compile }
+C unable to confirm this bug on egcs 1.0.1 for i586-pc-sco3.2v5.0.4 robertl
+C
+C Date: Sat, 23 Aug 1997 00:47:53 -0400 (EDT)
+C From: David Bristow
+C To: egcs-bugs@cygnus.com
+C Subject: g77 crashes compiling Dungeon
+C Message-ID:
+C
+C The following small segment of Dungeon (the adventure that became the
+C commercial hit Zork) causes an internal error in f771. The platform is
+C i586-pc-linux-gnulibc1, the compiler is egcs-ss-970821 (g77-GNU Fortran
+C 0.5.21-19970811)
+C
+C --cut here--cut here--cut here--cut here--cut here--cut here--
+C g77 --verbose -fugly -fvxt -c subr_.f
+C g77 version 0.5.21-19970811
+C gcc --verbose -fugly -fvxt -xf77 subr_.f -xnone -lf2c -lm
+C Reading specs from /usr/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.90.01/specs
+C gcc version egcs-2.90.01 970821 (gcc2-970802 experimental)
+C /usr/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.90.01/f771 subr_.f -fset-g77-defaults -quiet -dumpbase subr_.f -version -fversion -fugly -fvxt -o /tmp/cca23974.s
+C f771: warning: -fugly is overloaded with meanings and likely to be removed;
+C f771: warning: use only the specific -fugly-* options you need
+C GNU F77 version egcs-2.90.01 970821 (gcc2-970802 experimental) (i586-pc-linux-gnulibc1) compiled by GNU C version egcs-2.90.01 970821 (gcc2-970802 experimental).
+C GNU Fortran Front End version 0.5.21-19970811
+C f/com.c:941: failed assertion `TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e))'
+C gcc: Internal compiler error: program f771 got fatal signal 6
+C --cut here--cut here--cut here--cut here--cut here--cut here--
+C
+C Here's the FORTRAN code, it's basically a single subroutine from subr.f
+C in the Dungeon source, slightly altered (the original calls RAN(), which
+C doesn't exist in the g77 runtime)
+C
+C RND - Return a random integer mod n
+C
+ INTEGER FUNCTION RND (N)
+ IMPLICIT INTEGER (A-Z)
+ REAL RAND
+ COMMON /SEED/ RNSEED
+
+ RND = RAND(RNSEED)*FLOAT(N)
+ RETURN
+
+ END
Index: Fortran/gfortran/regression/g77/980310-3.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980310-3.f
@@ -0,0 +1,261 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+c
+c This demonstrates a problem with g77 and pic on x86 where
+c egcs 1.0.1 and earlier will generate bogus assembler output.
+c unfortunately, gas accepts the bogus acssembler output and
+c generates code that almost works.
+c
+
+
+C Date: Wed, 17 Dec 1997 23:20:29 +0000
+C From: Joao Cardoso
+C To: egcs-bugs@cygnus.com
+C Subject: egcs-1.0 f77 bug on OSR5
+C When trying to compile the Fortran file that I enclose bellow,
+C I got an assembler error:
+C
+C ./g77 -B./ -fpic -O -c scaleg.f
+C /usr/tmp/cca002D8.s:123:syntax error at (
+C
+C ./g77 -B./ -fpic -O0 -c scaleg.f
+C /usr/tmp/cca002EW.s:246:invalid operand combination: leal
+C
+C Compiling without the -fpic flag runs OK.
+
+ subroutine scaleg (n,ma,a,mb,b,low,igh,cscale,cperm,wk)
+c
+c *****parameters:
+ integer igh,low,ma,mb,n
+ double precision a(ma,n),b(mb,n),cperm(n),cscale(n),wk(n,6)
+c
+c *****local variables:
+ integer i,ir,it,j,jc,kount,nr,nrp2
+ double precision alpha,basl,beta,cmax,coef,coef2,coef5,cor,
+ * ew,ewc,fi,fj,gamma,pgamma,sum,t,ta,tb,tc
+c
+c *****fortran functions:
+ double precision dabs, dlog10, dsign
+c float
+c
+c *****subroutines called:
+c none
+c
+c ---------------------------------------------------------------
+c
+c *****purpose:
+c scales the matrices a and b in the generalized eigenvalue
+c problem a*x = (lambda)*b*x such that the magnitudes of the
+c elements of the submatrices of a and b (as specified by low
+c and igh) are close to unity in the least squares sense.
+c ref.: ward, r. c., balancing the generalized eigenvalue
+c problem, siam j. sci. stat. comput., vol. 2, no. 2, june 1981,
+c 141-152.
+c
+c *****parameter description:
+c
+c on input:
+c
+c ma,mb integer
+c row dimensions of the arrays containing matrices
+c a and b respectively, as declared in the main calling
+c program dimension statement;
+c
+c n integer
+c order of the matrices a and b;
+c
+c a real(ma,n)
+c contains the a matrix of the generalized eigenproblem
+c defined above;
+c
+c b real(mb,n)
+c contains the b matrix of the generalized eigenproblem
+c defined above;
+c
+c low integer
+c specifies the beginning -1 for the rows and
+c columns of a and b to be scaled;
+c
+c igh integer
+c specifies the ending -1 for the rows and columns
+c of a and b to be scaled;
+c
+c cperm real(n)
+c work array. only locations low through igh are
+c referenced and altered by this subroutine;
+c
+c wk real(n,6)
+c work array that must contain at least 6*n locations.
+c only locations low through igh, n+low through n+igh,
+c ..., 5*n+low through 5*n+igh are referenced and
+c altered by this subroutine.
+c
+c on output:
+c
+c a,b contain the scaled a and b matrices;
+c
+c cscale real(n)
+c contains in its low through igh locations the integer
+c exponents of 2 used for the column scaling factors.
+c the other locations are not referenced;
+c
+c wk contains in its low through igh locations the integer
+c exponents of 2 used for the row scaling factors.
+c
+c *****algorithm notes:
+c none.
+c
+c *****history:
+c written by r. c. ward.......
+c modified 8/86 by bobby bodenheimer so that if
+c sum = 0 (corresponding to the case where the matrix
+c doesn't need to be scaled) the routine returns.
+c
+c ---------------------------------------------------------------
+c
+ if (low .eq. igh) go to 410
+ do 210 i = low,igh
+ wk(i,1) = 0.0d0
+ wk(i,2) = 0.0d0
+ wk(i,3) = 0.0d0
+ wk(i,4) = 0.0d0
+ wk(i,5) = 0.0d0
+ wk(i,6) = 0.0d0
+ cscale(i) = 0.0d0
+ cperm(i) = 0.0d0
+ 210 continue
+c
+c compute right side vector in resulting linear equations
+c
+ basl = dlog10(2.0d0)
+ do 240 i = low,igh
+ do 240 j = low,igh
+ tb = b(i,j)
+ ta = a(i,j)
+ if (ta .eq. 0.0d0) go to 220
+ ta = dlog10(dabs(ta)) / basl
+ 220 continue
+ if (tb .eq. 0.0d0) go to 230
+ tb = dlog10(dabs(tb)) / basl
+ 230 continue
+ wk(i,5) = wk(i,5) - ta - tb
+ wk(j,6) = wk(j,6) - ta - tb
+ 240 continue
+ nr = igh-low+1
+ coef = 1.0d0/float(2*nr)
+ coef2 = coef*coef
+ coef5 = 0.5d0*coef2
+ nrp2 = nr+2
+ beta = 0.0d0
+ it = 1
+c
+c start generalized conjugate gradient iteration
+c
+ 250 continue
+ ew = 0.0d0
+ ewc = 0.0d0
+ gamma = 0.0d0
+ do 260 i = low,igh
+ gamma = gamma + wk(i,5)*wk(i,5) + wk(i,6)*wk(i,6)
+ ew = ew + wk(i,5)
+ ewc = ewc + wk(i,6)
+ 260 continue
+ gamma = coef*gamma - coef2*(ew**2 + ewc**2)
+ + - coef5*(ew - ewc)**2
+ if (it .ne. 1) beta = gamma / pgamma
+ t = coef5*(ewc - 3.0d0*ew)
+ tc = coef5*(ew - 3.0d0*ewc)
+ do 270 i = low,igh
+ wk(i,2) = beta*wk(i,2) + coef*wk(i,5) + t
+ cperm(i) = beta*cperm(i) + coef*wk(i,6) + tc
+ 270 continue
+c
+c apply matrix to vector
+c
+ do 300 i = low,igh
+ kount = 0
+ sum = 0.0d0
+ do 290 j = low,igh
+ if (a(i,j) .eq. 0.0d0) go to 280
+ kount = kount+1
+ sum = sum + cperm(j)
+ 280 continue
+ if (b(i,j) .eq. 0.0d0) go to 290
+ kount = kount+1
+ sum = sum + cperm(j)
+ 290 continue
+ wk(i,3) = float(kount)*wk(i,2) + sum
+ 300 continue
+ do 330 j = low,igh
+ kount = 0
+ sum = 0.0d0
+ do 320 i = low,igh
+ if (a(i,j) .eq. 0.0d0) go to 310
+ kount = kount+1
+ sum = sum + wk(i,2)
+ 310 continue
+ if (b(i,j) .eq. 0.0d0) go to 320
+ kount = kount+1
+ sum = sum + wk(i,2)
+ 320 continue
+ wk(j,4) = float(kount)*cperm(j) + sum
+ 330 continue
+ sum = 0.0d0
+ do 340 i = low,igh
+ sum = sum + wk(i,2)*wk(i,3) + cperm(i)*wk(i,4)
+ 340 continue
+ if(sum.eq.0.0d0) return
+ alpha = gamma / sum
+c
+c determine correction to current iterate
+c
+ cmax = 0.0d0
+ do 350 i = low,igh
+ cor = alpha * wk(i,2)
+ if (dabs(cor) .gt. cmax) cmax = dabs(cor)
+ wk(i,1) = wk(i,1) + cor
+ cor = alpha * cperm(i)
+ if (dabs(cor) .gt. cmax) cmax = dabs(cor)
+ cscale(i) = cscale(i) + cor
+ 350 continue
+ if (cmax .lt. 0.5d0) go to 370
+ do 360 i = low,igh
+ wk(i,5) = wk(i,5) - alpha*wk(i,3)
+ wk(i,6) = wk(i,6) - alpha*wk(i,4)
+ 360 continue
+ pgamma = gamma
+ it = it+1
+ if (it .le. nrp2) go to 250
+c
+c end generalized conjugate gradient iteration
+c
+ 370 continue
+ do 380 i = low,igh
+ ir = wk(i,1) + dsign(0.5d0,wk(i,1))
+ wk(i,1) = ir
+ jc = cscale(i) + dsign(0.5d0,cscale(i))
+ cscale(i) = jc
+ 380 continue
+c
+c scale a and b
+c
+ do 400 i = 1,igh
+ ir = wk(i,1)
+ fi = 2.0d0**ir
+ if (i .lt. low) fi = 1.0d0
+ do 400 j =low,n
+ jc = cscale(j)
+ fj = 2.0d0**jc
+ if (j .le. igh) go to 390
+ if (i .lt. low) go to 400
+ fj = 1.0d0
+ 390 continue
+ a(i,j) = a(i,j)*fi*fj
+ b(i,j) = b(i,j)*fi*fj
+ 400 continue
+ 410 continue
+ return
+c
+c last line of scaleg
+c
+ end
Index: Fortran/gfortran/regression/g77/980310-4.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980310-4.f
@@ -0,0 +1,348 @@
+c { dg-do compile }
+C To: egcs-bugs@cygnus.com
+C Subject: -fPIC problem showing up with fortran on x86
+C From: Dave Love
+C Date: 19 Dec 1997 19:31:41 +0000
+C
+C
+C This illustrates a long-standing problem noted at the end of the g77
+C `Actual Bugs' info node and thought to be in the back end. Although
+C the report is against gcc 2.7 I can reproduce it (specifically on
+C redhat 4.2) with the 971216 egcs snapshot.
+C
+C g77 version 0.5.21
+C gcc -v -fnull-version -o /tmp/gfa00415 -xf77-cpp-input /tmp/gfa00415.f -xnone
+C -lf2c -lm
+C
+
+C ------------
+ subroutine dqage(f,a,b,epsabs,epsrel,limit,result,abserr,
+ * neval,ier,alist,blist,rlist,elist,iord,last)
+C --------------------------------------------------
+C
+C Modified Feb 1989 by Barry W. Brown to eliminate key
+C as argument (use key=1) and to eliminate all Fortran
+C output.
+C
+C Purpose: to make this routine usable from within S.
+C
+C --------------------------------------------------
+c***begin prologue dqage
+c***date written 800101 (yymmdd)
+c***revision date 830518 (yymmdd)
+c***category no. h2a1a1
+c***keywords automatic integrator, general-purpose,
+c integrand examinator, globally adaptive,
+c gauss-kronrod
+c***author piessens,robert,appl. math. & progr. div. - k.u.leuven
+c de doncker,elise,appl. math. & progr. div. - k.u.leuven
+c***purpose the routine calculates an approximation result to a given
+c definite integral i = integral of f over (a,b),
+c hopefully satisfying following claim for accuracy
+c abs(i-reslt).le.max(epsabs,epsrel*abs(i)).
+c***description
+c
+c computation of a definite integral
+c standard fortran subroutine
+c double precision version
+c
+c parameters
+c on entry
+c f - double precision
+c function subprogram defining the integrand
+c function f(x). the actual name for f needs to be
+c declared e x t e r n a l in the driver program.
+c
+c a - double precision
+c lower limit of integration
+c
+c b - double precision
+c upper limit of integration
+c
+c epsabs - double precision
+c absolute accuracy requested
+c epsrel - double precision
+c relative accuracy requested
+c if epsabs.le.0
+c and epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
+c the routine will end with ier = 6.
+c
+c key - integer
+c key for choice of local integration rule
+c a gauss-kronrod pair is used with
+c 7 - 15 points if key.lt.2,
+c 10 - 21 points if key = 2,
+c 15 - 31 points if key = 3,
+c 20 - 41 points if key = 4,
+c 25 - 51 points if key = 5,
+c 30 - 61 points if key.gt.5.
+c
+c limit - integer
+c gives an upperbound on the number of subintervals
+c in the partition of (a,b), limit.ge.1.
+c
+c on return
+c result - double precision
+c approximation to the integral
+c
+c abserr - double precision
+c estimate of the modulus of the absolute error,
+c which should equal or exceed abs(i-result)
+c
+c neval - integer
+c number of integrand evaluations
+c
+c ier - integer
+c ier = 0 normal and reliable termination of the
+c routine. it is assumed that the requested
+c accuracy has been achieved.
+c ier.gt.0 abnormal termination of the routine
+c the estimates for result and error are
+c less reliable. it is assumed that the
+c requested accuracy has not been achieved.
+c error messages
+c ier = 1 maximum number of subdivisions allowed
+c has been achieved. one can allow more
+c subdivisions by increasing the value
+c of limit.
+c however, if this yields no improvement it
+c is rather advised to analyze the integrand
+c in order to determine the integration
+c difficulties. if the position of a local
+c difficulty can be determined(e.g.
+c singularity, discontinuity within the
+c interval) one will probably gain from
+c splitting up the interval at this point
+c and calling the integrator on the
+c subranges. if possible, an appropriate
+c special-purpose integrator should be used
+c which is designed for handling the type of
+c difficulty involved.
+c = 2 the occurrence of roundoff error is
+c detected, which prevents the requested
+c tolerance from being achieved.
+c = 3 extremely bad integrand behavior occurs
+c at some points of the integration
+c interval.
+c = 6 the input is invalid, because
+c (epsabs.le.0 and
+c epsrel.lt.max(50*rel.mach.acc.,0.5d-28),
+c result, abserr, neval, last, rlist(1) ,
+c elist(1) and iord(1) are set to zero.
+c alist(1) and blist(1) are set to a and b
+c respectively.
+c
+c alist - double precision
+c vector of dimension at least limit, the first
+c last elements of which are the left
+c end points of the subintervals in the partition
+c of the given integration range (a,b)
+c
+c blist - double precision
+c vector of dimension at least limit, the first
+c last elements of which are the right
+c end points of the subintervals in the partition
+c of the given integration range (a,b)
+c
+c rlist - double precision
+c vector of dimension at least limit, the first
+c last elements of which are the
+c integral approximations on the subintervals
+c
+c elist - double precision
+c vector of dimension at least limit, the first
+c last elements of which are the moduli of the
+c absolute error estimates on the subintervals
+c
+c iord - integer
+c vector of dimension at least limit, the first k
+c elements of which are pointers to the
+c error estimates over the subintervals,
+c such that elist(iord(1)), ...,
+c elist(iord(k)) form a decreasing sequence,
+c with k = last if last.le.(limit/2+2), and
+c k = limit+1-last otherwise
+c
+c last - integer
+c number of subintervals actually produced in the
+c subdivision process
+c
+c***references (none)
+c***routines called d1mach,dqk15,dqk21,dqk31,
+c dqk41,dqk51,dqk61,dqpsrt
+c***end prologue dqage
+c
+ double precision a,abserr,alist,area,area1,area12,area2,a1,a2,b,
+ * blist,b1,b2,dabs,defabs,defab1,defab2,dmax1,d1mach,elist,epmach,
+ * epsabs,epsrel,errbnd,errmax,error1,error2,erro12,errsum,f,
+ * resabs,result,rlist,uflow
+ integer ier,iord,iroff1,iroff2,k,last,limit,maxerr,neval,
+ * nrmax
+c
+ dimension alist(limit),blist(limit),elist(limit),iord(limit),
+ * rlist(limit)
+c
+ external f
+c
+c list of major variables
+c -----------------------
+c
+c alist - list of left end points of all subintervals
+c considered up to now
+c blist - list of right end points of all subintervals
+c considered up to now
+c rlist(i) - approximation to the integral over
+c (alist(i),blist(i))
+c elist(i) - error estimate applying to rlist(i)
+c maxerr - pointer to the interval with largest
+c error estimate
+c errmax - elist(maxerr)
+c area - sum of the integrals over the subintervals
+c errsum - sum of the errors over the subintervals
+c errbnd - requested accuracy max(epsabs,epsrel*
+c abs(result))
+c *****1 - variable for the left subinterval
+c *****2 - variable for the right subinterval
+c last - index for subdivision
+c
+c
+c machine dependent constants
+c ---------------------------
+c
+c epmach is the largest relative spacing.
+c uflow is the smallest positive magnitude.
+c
+c***first executable statement dqage
+ epmach = d1mach(4)
+ uflow = d1mach(1)
+c
+c test on validity of parameters
+c ------------------------------
+c
+ ier = 0
+ neval = 0
+ last = 0
+ result = 0.0d+00
+ abserr = 0.0d+00
+ alist(1) = a
+ blist(1) = b
+ rlist(1) = 0.0d+00
+ elist(1) = 0.0d+00
+ iord(1) = 0
+ if(epsabs.le.0.0d+00.and.
+ * epsrel.lt.dmax1(0.5d+02*epmach,0.5d-28)) ier = 6
+ if(ier.eq.6) go to 999
+c
+c first approximation to the integral
+c -----------------------------------
+c
+ neval = 0
+ call dqk15(f,a,b,result,abserr,defabs,resabs)
+ last = 1
+ rlist(1) = result
+ elist(1) = abserr
+ iord(1) = 1
+c
+c test on accuracy.
+c
+ errbnd = dmax1(epsabs,epsrel*dabs(result))
+ if(abserr.le.0.5d+02*epmach*defabs.and.abserr.gt.errbnd) ier = 2
+ if(limit.eq.1) ier = 1
+ if(ier.ne.0.or.(abserr.le.errbnd.and.abserr.ne.resabs)
+ * .or.abserr.eq.0.0d+00) go to 60
+c
+c initialization
+c --------------
+c
+c
+ errmax = abserr
+ maxerr = 1
+ area = result
+ errsum = abserr
+ nrmax = 1
+ iroff1 = 0
+ iroff2 = 0
+c
+c main do-loop
+c ------------
+c
+ do 30 last = 2,limit
+c
+c bisect the subinterval with the largest error estimate.
+c
+ a1 = alist(maxerr)
+ b1 = 0.5d+00*(alist(maxerr)+blist(maxerr))
+ a2 = b1
+ b2 = blist(maxerr)
+ call dqk15(f,a1,b1,area1,error1,resabs,defab1)
+ call dqk15(f,a2,b2,area2,error2,resabs,defab2)
+c
+c improve previous approximations to integral
+c and error and test for accuracy.
+c
+ neval = neval+1
+ area12 = area1+area2
+ erro12 = error1+error2
+ errsum = errsum+erro12-errmax
+ area = area+area12-rlist(maxerr)
+ if(defab1.eq.error1.or.defab2.eq.error2) go to 5
+ if(dabs(rlist(maxerr)-area12).le.0.1d-04*dabs(area12)
+ * .and.erro12.ge.0.99d+00*errmax) iroff1 = iroff1+1
+ if(last.gt.10.and.erro12.gt.errmax) iroff2 = iroff2+1
+ 5 rlist(maxerr) = area1
+ rlist(last) = area2
+ errbnd = dmax1(epsabs,epsrel*dabs(area))
+ if(errsum.le.errbnd) go to 8
+c
+c test for roundoff error and eventually set error flag.
+c
+ if(iroff1.ge.6.or.iroff2.ge.20) ier = 2
+c
+c set error flag in the case that the number of subintervals
+c equals limit.
+c
+ if(last.eq.limit) ier = 1
+c
+c set error flag in the case of bad integrand behavior
+c at a point of the integration range.
+c
+ if(dmax1(dabs(a1),dabs(b2)).le.(0.1d+01+0.1d+03*
+ * epmach)*(dabs(a2)+0.1d+04*uflow)) ier = 3
+c
+c append the newly-created intervals to the list.
+c
+ 8 if(error2.gt.error1) go to 10
+ alist(last) = a2
+ blist(maxerr) = b1
+ blist(last) = b2
+ elist(maxerr) = error1
+ elist(last) = error2
+ go to 20
+ 10 alist(maxerr) = a2
+ alist(last) = a1
+ blist(last) = b1
+ rlist(maxerr) = area2
+ rlist(last) = area1
+ elist(maxerr) = error2
+ elist(last) = error1
+c
+c call subroutine dqpsrt to maintain the descending ordering
+c in the list of error estimates and select the subinterval
+c with the largest error estimate (to be bisected next).
+c
+ 20 call dqpsrt(limit,last,maxerr,errmax,elist,iord,nrmax)
+c ***jump out of do-loop
+ if(ier.ne.0.or.errsum.le.errbnd) go to 40
+ 30 continue
+c
+c compute final result.
+c ---------------------
+c
+ 40 result = 0.0d+00
+ do 50 k=1,last
+ result = result+rlist(k)
+ 50 continue
+ abserr = errsum
+ 60 neval = 30*neval+15
+ 999 return
+ end
Index: Fortran/gfortran/regression/g77/980310-6.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980310-6.f
@@ -0,0 +1,22 @@
+c { dg-do compile }
+C From: Norbert Conrad
+C Message-Id: <199711131008.LAA12272@marvin.hrz.uni-giessen.de>
+C Subject: 971105 g77 bug
+C To: egcs-bugs@cygnus.com
+C Date: Thu, 13 Nov 1997 11:08:19 +0100 (CET)
+
+C I found a bug in g77 in snapshot 971105
+
+ subroutine ai (a)
+ dimension a(-1:*)
+ return
+ end
+C ai.f: In subroutine `ai':
+C ai.f:1:
+C subroutine ai (a)
+C ^
+C Array `a' at (^) is too large to handle
+C
+C This happens whenever the lower index boundary is negative and the upper index
+C boundary is '*'.
+
Index: Fortran/gfortran/regression/g77/980310-7.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980310-7.f
@@ -0,0 +1,51 @@
+c { dg-do compile }
+C From: "David C. Doherty"
+C Message-Id: <199711171846.MAA27947@uh.msc.edu>
+C Subject: g77: auto arrays + goto = no go
+C To: egcs-bugs@cygnus.com
+C Date: Mon, 17 Nov 1997 12:46:27 -0600 (CST)
+
+C I sent the following to fortran@gnu.ai.mit.edu, and Dave Love
+C replied that he was able to reproduce it on rs6000-aix; not on
+C others. He suggested that I send it to egcs-bugs.
+
+C Hi - I've observed the following behavior regarding
+C automatic arrays and gotos. Seems similar to what I found
+C in the docs about computed gotos (but not exactly the same).
+C
+C I suspect from the nature of the error msg that it's in the GBE.
+C
+C I'm using egcs-971105, under linux-ppc.
+C
+C I also observed the same in g77-0.5.19 (and gcc 2.7.2?).
+C
+C I'd appreciate any advice on this. thanks for the great work.
+C --
+C >cat testg77.f
+ subroutine testg77(n, a)
+c
+ implicit none
+c
+ integer n
+ real a(n)
+ real b(n)
+ integer i
+c
+ do i = 1, 10
+ if (i .gt. 4) goto 100
+ write(0, '(i2)')i
+ enddo
+c
+ goto 200
+100 continue
+200 continue
+c
+ return
+ end
+C >g77 -c testg77.f
+C testg77.f: In subroutine `testg77':
+C testg77.f:19: label `200' used before containing binding contour
+C testg77.f:18: label `100' used before containing binding contour
+C --
+C If I comment out the b(n) line or replace it with, e.g., b(10),
+C it compiles fine.
Index: Fortran/gfortran/regression/g77/980310-8.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980310-8.f
@@ -0,0 +1,41 @@
+c { dg-do compile }
+C To: egcs-bugs@cygnus.com
+C Subject: egcs-g77 and array indexing
+C Reply-To: etseidl@jutland.ca.sandia.gov
+C Date: Wed, 26 Nov 1997 10:38:27 -0800
+C From: Edward Seidl
+C
+C I have some horrible spaghetti code I'm trying compile with egcs-g77,
+C but it's puking on code like the example below. I have no idea if it's
+C legal fortran or not, and I'm in no position to change it. All I do know
+C is it compiles with a number of other compilers, including f2c and
+C g77-0.5.19.1/gcc-2.7.2.1. When I try to compile with egcs-2.90.18 971122
+C I get the following (on both i686-pc-linux-gnu and
+C alphaev56-unknown-linux-gnu):
+C
+Cfoo.f: In subroutine `foobar':
+Cfoo.f:11:
+C subroutine foobar(norb,nnorb)
+C ^
+CArray `norb' at (^) is too large to handle
+
+ program foo
+ implicit integer(A-Z)
+ dimension norb(6)
+ nnorb=6
+
+ call foobar(norb,nnorb)
+
+ stop
+ end
+
+ subroutine foobar(norb,nnorb)
+ implicit integer(A-Z)
+ dimension norb(-1:*)
+
+ do 10 i=-1,nnorb-2
+ norb(i) = i+999
+ 10 continue
+
+ return
+ end
Index: Fortran/gfortran/regression/g77/980419-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980419-2.f
@@ -0,0 +1,51 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+c
+c SEGVs in loop.c with -O2.
+
+ character*80 function nxtlin(lun,ierr,itok)
+ character onechr*1,twochr*2,thrchr*3
+ itok=0
+ do while (.true.)
+ read (lun,'(a)',iostat=ierr) nxtlin
+ if (nxtlin(1:1).ne.'#') then
+ ito=0
+ do 10 it=1,79
+ if (nxtlin(it:it).ne.' ' .and. nxtlin(it+1:it+1).eq.' ')
+ $ then
+ itast=0
+ itstrt=0
+ do itt=ito+1,it
+ if (nxtlin(itt:itt).eq.'*') itast=itt
+ enddo
+ itstrt=ito+1
+ do while (nxtlin(itstrt:itstrt).eq.' ')
+ itstrt=itstrt+1
+ enddo
+ if (itast.gt.0) then
+ nchrs=itast-itstrt
+ if (nchrs.eq.1) then
+ onechr=nxtlin(itstrt:itstrt)
+ read (onechr,*) itokn
+ elseif (nchrs.eq.2) then
+ twochr=nxtlin(itstrt:itstrt+1)
+ read (twochr,*) itokn
+ elseif (nchrs.eq.3) then
+ thrchr=nxtlin(itstrt:itstrt+2)
+ read (thrchr,*) itokn
+ elseif (nchrs.eq.4) then
+ thrchr=nxtlin(itstrt:itstrt+3)
+ read (thrchr,*) itokn
+ endif
+ itok=itok+itokn
+ else
+ itok=itok+1
+ endif
+ ito=it+1
+ endif
+ 10 continue
+ return
+ endif
+ enddo
+ return
+ end
Index: Fortran/gfortran/regression/g77/980424-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980424-0.f
@@ -0,0 +1,7 @@
+c { dg-do compile }
+C crashes in subst_stack_regs_pat on x86-linux, in the "abort();"
+C within the switch statement.
+ SUBROUTINE C(A)
+ COMPLEX A
+ WRITE(*,*) A.NE.CMPLX(0.0D0)
+ END
Index: Fortran/gfortran/regression/g77/980427-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980427-0.f
@@ -0,0 +1,9 @@
+c { dg-do compile }
+c ../../egcs/gcc/f/com.c:938: failed assertion `TREE_CODE (TREE_TYPE (e)) == REAL_TYPE'
+c Fixed by 28-04-1998 global.c (ffeglobal_ref_progunit_) change.
+ external b
+ call y(b)
+ end
+ subroutine x
+ a = b()
+ end
Index: Fortran/gfortran/regression/g77/980519-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980519-2.f
@@ -0,0 +1,51 @@
+c { dg-do compile }
+* Date: Fri, 17 Apr 1998 14:12:51 +0200
+* From: Jean-Paul Jeannot
+* Organization: GX Technology France
+* To: egcs-bugs@cygnus.com
+* Subject: identified bug in g77 on Alpha
+*
+* Dear Sir,
+*
+* You will find below the assembly code of a simple Fortran routine which
+* crashes with segmentation fault when storing the first element
+* in( jT_f-hd_T ) = Xsp
+* whereas everything is fine when commenting this line.
+*
+* The assembly code (generated with
+* -ffast-math -fexpensive-optimizations -fomit-frame-pointer -fno-inline
+* or with -O5)
+* uses a zapnot instruction to copy an address.
+* BUT the zapnot parameter is 15 (copuing 4 bytes) instead of 255 (to copy
+* 8 bytes).
+*
+* I guess this is typically a 64 bit issue. As, from my understanding,
+* zapnots are used a lot to copy registers, this may create problems
+* elsewhere.
+*
+* Thanks for your help
+*
+* Jean-Paul Jeannot
+*
+ subroutine simul_trace( in, Xsp, Ysp, Xrcv, Yrcv )
+
+c Next declaration added on transfer to gfortran testsuite
+ integer hd_S, hd_Z, hd_T
+
+ common /Idim/ jT_f, jT_l, nT, nT_dim
+ common /Idim/ jZ_f, jZ_l, nZ, nZ_dim
+ common /Idim/ jZ2_f, jZ2_l, nZ2, nZ2_dim
+ common /Idim/ jzs_f, jzs_l, nzs, nzs_dim, l_amp
+ common /Idim/ hd_S, hd_Z, hd_T
+ common /Idim/ nlay, nlayz
+ common /Idim/ n_work
+ common /Idim/ nb_calls
+
+ real Xsp, Ysp, Xrcv, Yrcv
+ real in( jT_f-hd_T : jT_l )
+
+ in( jT_f-hd_T ) = Xsp
+ in( jT_f-hd_T + 1 ) = Ysp
+ in( jT_f-hd_T + 2 ) = Xrcv
+ in( jT_f-hd_T + 3 ) = Yrcv
+ end
Index: Fortran/gfortran/regression/g77/980520-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980520-1.f
@@ -0,0 +1,9 @@
+c { dg-do run }
+c { dg-options "-std=legacy" }
+c
+c Produced a link error through not eliminating the unused statement
+c function after 1998-05-15 change to gcc/toplev.c. It's in
+c `execute' since it needs to link.
+c Fixed by 1998-05-23 change to f/com.c.
+ values(i,j) = val((i-1)*n+j)
+ end
Index: Fortran/gfortran/regression/g77/980615-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980615-0.f
@@ -0,0 +1,12 @@
+c { dg-do compile }
+* Fixed by JCB 1998-07-25 change to stc.c.
+
+* Date: Thu, 11 Jun 1998 22:35:20 -0500
+* From: Ian A Watson
+* Subject: crash
+*
+ CaLL foo(W)
+ END
+ SUBROUTINE foo(W)
+ yy(I)=A(I)Q(X) ! { dg-error "Unclassifiable statement" }
+c { dg-error "end of file" "end of file" { target *-*-* } 0 }
Index: Fortran/gfortran/regression/g77/980616-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980616-0.f
@@ -0,0 +1,10 @@
+c { dg-do compile }
+* Fixed by 1998-07-11 equiv.c change.
+* ../../gcc/f/equiv.c:666: failed assertion `ffebld_op (subscript) == FFEBLD_opCONTER'
+
+* Date: Mon, 15 Jun 1998 21:54:32 -0500
+* From: Ian A Watson
+* Subject: Mangler Crash
+ EQUIVALENCE(I,glerf(P)) ! { dg-error "is a variable" "is a variable" }
+ COMMON /foo/ glerf(3)
+c { dg-error "end of file" "end of file" { target *-*-* } 0 }
Index: Fortran/gfortran/regression/g77/980628-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980628-0.f
@@ -0,0 +1,62 @@
+c { dg-do run }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+ equivalence (r1(2), d1)
+ equivalence (r2(2), d2)
+ equivalence (r3(2), d3)
+
+ r1(1) = 1.
+ d1 = 10.
+ r1(4) = 1.
+ r1(5) = 1.
+ i1 = 1
+ r2(1) = 2.
+ d2 = 20.
+ r2(4) = 2.
+ r2(5) = 2.
+ i2 = 2
+ r3(1) = 3.
+ d3 = 30.
+ r3(4) = 3.
+ r3(5) = 3.
+ i3 = 3
+
+ call x (r1, d1, i1, r2, d2, i2, r3, d3, i3)
+
+ end
+
+ subroutine x (r1, d1, i1, r2, d2, i2, r3, d3, i3)
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+
+ if (r1(1) .ne. 1.) STOP 1
+ if (d1 .ne. 10.) STOP 2
+ if (r1(4) .ne. 1.) STOP 3
+ if (r1(5) .ne. 1.) STOP 4
+ if (i1 .ne. 1) STOP 5
+ if (r2(1) .ne. 2.) STOP 6
+ if (d2 .ne. 20.) STOP 7
+ if (r2(4) .ne. 2.) STOP 8
+ if (r2(5) .ne. 2.) STOP 9
+ if (i2 .ne. 2) STOP 10
+ if (r3(1) .ne. 3.) STOP 11
+ if (d3 .ne. 30.) STOP 12
+ if (r3(4) .ne. 3.) STOP 13
+ if (r3(5) .ne. 3.) STOP 14
+ if (i3 .ne. 3) STOP 15
+
+ end
Index: Fortran/gfortran/regression/g77/980628-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980628-1.f
@@ -0,0 +1,63 @@
+c { dg-do run }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+ save
+
+ real r1(5), r2(5), r3(5)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+ equivalence (r1(2), d1)
+ equivalence (r2(2), d2)
+ equivalence (r3(2), d3)
+
+ r1(1) = 1.
+ d1 = 10.
+ r1(4) = 1.
+ r1(5) = 1.
+ i1 = 1
+ r2(1) = 2.
+ d2 = 20.
+ r2(4) = 2.
+ r2(5) = 2.
+ i2 = 2
+ r3(1) = 3.
+ d3 = 30.
+ r3(4) = 3.
+ r3(5) = 3.
+ i3 = 3
+
+ call x (r1, d1, i1, r2, d2, i2, r3, d3, i3)
+
+ end
+
+ subroutine x (r1, d1, i1, r2, d2, i2, r3, d3, i3)
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+
+ if (r1(1) .ne. 1.) STOP 1
+ if (d1 .ne. 10.) STOP 2
+ if (r1(4) .ne. 1.) STOP 3
+ if (r1(5) .ne. 1.) STOP 4
+ if (i1 .ne. 1) STOP 5
+ if (r2(1) .ne. 2.) STOP 6
+ if (d2 .ne. 20.) STOP 7
+ if (r2(4) .ne. 2.) STOP 8
+ if (r2(5) .ne. 2.) STOP 9
+ if (i2 .ne. 2) STOP 10
+ if (r3(1) .ne. 3.) STOP 11
+ if (d3 .ne. 30.) STOP 12
+ if (r3(4) .ne. 3.) STOP 13
+ if (r3(5) .ne. 3.) STOP 14
+ if (i3 .ne. 3) STOP 15
+
+ end
Index: Fortran/gfortran/regression/g77/980628-10.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980628-10.f
@@ -0,0 +1,59 @@
+c { dg-do run }
+c { dg-options "-std=gnu" }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+ save
+
+ character c1(11), c2(11), c3(11)
+ real r1, r2, r3
+ character c4, c5, c6
+ equivalence (r1, c1(2))
+ equivalence (r2, c2(2))
+ equivalence (r3, c3(2))
+
+ c1(1) = '1'
+ r1 = 1.
+ c1(11) = '1'
+ c4 = '4'
+ c2(1) = '2'
+ r2 = 2.
+ c2(11) = '2'
+ c5 = '5'
+ c3(1) = '3'
+ r3 = 3.
+ c3(11) = '3'
+ c6 = '6'
+
+ call x (c1, r1, c2, r2, c3, r3, c4, c5, c6)
+
+ end
+
+ subroutine x (c1, r1, c2, r2, c3, r3, c4, c5, c6)
+ implicit none
+
+ character c1(11), c2(11), c3(11)
+ real r1, r2, r3
+ character c4, c5, c6
+
+ if (c1(1) .ne. '1') STOP 1
+ if (r1 .ne. 1.) STOP 2
+ if (c1(11) .ne. '1') STOP 3
+ if (c4 .ne. '4') STOP 4
+ if (c2(1) .ne. '2') STOP 5
+ if (r2 .ne. 2.) STOP 6
+ if (c2(11) .ne. '2') STOP 7
+ if (c5 .ne. '5') STOP 8
+ if (c3(1) .ne. '3') STOP 9
+ if (r3 .ne. 3.) STOP 10
+ if (c3(11) .ne. '3') STOP 11
+ if (c6 .ne. '6') STOP 12
+
+ end
+
Index: Fortran/gfortran/regression/g77/980628-2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980628-2.f
@@ -0,0 +1,57 @@
+c { dg-do run }
+c { dg-options "-std=gnu" }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+
+ character c1(11), c2(11), c3(11)
+ real r1, r2, r3
+ character c4, c5, c6
+ equivalence (c1(2), r1)
+ equivalence (c2(2), r2)
+ equivalence (c3(2), r3)
+
+ c1(1) = '1'
+ r1 = 1.
+ c1(11) = '1'
+ c4 = '4'
+ c2(1) = '2'
+ r2 = 2.
+ c2(11) = '2'
+ c5 = '5'
+ c3(1) = '3'
+ r3 = 3.
+ c3(11) = '3'
+ c6 = '6'
+
+ call x (c1, r1, c2, r2, c3, r3, c4, c5, c6)
+
+ end
+
+ subroutine x (c1, r1, c2, r2, c3, r3, c4, c5, c6)
+ implicit none
+
+ character c1(11), c2(11), c3(11)
+ real r1, r2, r3
+ character c4, c5, c6
+
+ if (c1(1) .ne. '1') STOP 1
+ if (r1 .ne. 1.) STOP 2
+ if (c1(11) .ne. '1') STOP 3
+ if (c4 .ne. '4') STOP 4
+ if (c2(1) .ne. '2') STOP 5
+ if (r2 .ne. 2.) STOP 6
+ if (c2(11) .ne. '2') STOP 7
+ if (c5 .ne. '5') STOP 8
+ if (c3(1) .ne. '3') STOP 9
+ if (r3 .ne. 3.) STOP 10
+ if (c3(11) .ne. '3') STOP 11
+ if (c6 .ne. '6') STOP 12
+
+ end
Index: Fortran/gfortran/regression/g77/980628-3.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980628-3.f
@@ -0,0 +1,59 @@
+c { dg-do run }
+c { dg-options "-std=gnu" }
+c
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+ save
+
+ character c1(11), c2(11), c3(11)
+ real r1, r2, r3
+ character c4, c5, c6
+ equivalence (c1(2), r1)
+ equivalence (c2(2), r2)
+ equivalence (c3(2), r3)
+
+ c1(1) = '1'
+ r1 = 1.
+ c1(11) = '1'
+ c4 = '4'
+ c2(1) = '2'
+ r2 = 2.
+ c2(11) = '2'
+ c5 = '5'
+ c3(1) = '3'
+ r3 = 3.
+ c3(11) = '3'
+ c6 = '6'
+
+ call x (c1, r1, c2, r2, c3, r3, c4, c5, c6)
+
+ end
+
+ subroutine x (c1, r1, c2, r2, c3, r3, c4, c5, c6)
+ implicit none
+
+ character c1(11), c2(11), c3(11)
+ real r1, r2, r3
+ character c4, c5, c6
+
+ if (c1(1) .ne. '1') STOP 1
+ if (r1 .ne. 1.) STOP 2
+ if (c1(11) .ne. '1') STOP 3
+ if (c4 .ne. '4') STOP 4
+ if (c2(1) .ne. '2') STOP 5
+ if (r2 .ne. 2.) STOP 6
+ if (c2(11) .ne. '2') STOP 7
+ if (c5 .ne. '5') STOP 8
+ if (c3(1) .ne. '3') STOP 9
+ if (r3 .ne. 3.) STOP 10
+ if (c3(11) .ne. '3') STOP 11
+ if (c6 .ne. '6') STOP 12
+
+ end
Index: Fortran/gfortran/regression/g77/980628-7.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980628-7.f
@@ -0,0 +1,63 @@
+c { dg-do run }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+ equivalence (d1, r1(2))
+ equivalence (d2, r2(2))
+ equivalence (d3, r3(2))
+
+ r1(1) = 1.
+ d1 = 10.
+ r1(4) = 1.
+ r1(5) = 1.
+ i1 = 1
+ r2(1) = 2.
+ d2 = 20.
+ r2(4) = 2.
+ r2(5) = 2.
+ i2 = 2
+ r3(1) = 3.
+ d3 = 30.
+ r3(4) = 3.
+ r3(5) = 3.
+ i3 = 3
+
+ call x (r1, d1, i1, r2, d2, i2, r3, d3, i3)
+
+ end
+
+ subroutine x (r1, d1, i1, r2, d2, i2, r3, d3, i3)
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+
+ if (r1(1) .ne. 1.) STOP 1
+ if (d1 .ne. 10.) STOP 2
+ if (r1(4) .ne. 1.) STOP 3
+ if (r1(5) .ne. 1.) STOP 4
+ if (i1 .ne. 1) STOP 5
+ if (r2(1) .ne. 2.) STOP 6
+ if (d2 .ne. 20.) STOP 7
+ if (r2(4) .ne. 2.) STOP 8
+ if (r2(5) .ne. 2.) STOP 9
+ if (i2 .ne. 2) STOP 10
+ if (r3(1) .ne. 3.) STOP 11
+ if (d3 .ne. 30.) STOP 12
+ if (r3(4) .ne. 3.) STOP 13
+ if (r3(5) .ne. 3.) STOP 14
+ if (i3 .ne. 3) STOP 15
+
+ end
+
Index: Fortran/gfortran/regression/g77/980628-8.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980628-8.f
@@ -0,0 +1,64 @@
+c { dg-do run }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+ save
+
+ real r1(5), r2(5), r3(5)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+ equivalence (d1, r1(2))
+ equivalence (d2, r2(2))
+ equivalence (d3, r3(2))
+
+ r1(1) = 1.
+ d1 = 10.
+ r1(4) = 1.
+ r1(5) = 1.
+ i1 = 1
+ r2(1) = 2.
+ d2 = 20.
+ r2(4) = 2.
+ r2(5) = 2.
+ i2 = 2
+ r3(1) = 3.
+ d3 = 30.
+ r3(4) = 3.
+ r3(5) = 3.
+ i3 = 3
+
+ call x (r1, d1, i1, r2, d2, i2, r3, d3, i3)
+
+ end
+
+ subroutine x (r1, d1, i1, r2, d2, i2, r3, d3, i3)
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+
+ if (r1(1) .ne. 1.) STOP 1
+ if (d1 .ne. 10.) STOP 2
+ if (r1(4) .ne. 1.) STOP 3
+ if (r1(5) .ne. 1.) STOP 4
+ if (i1 .ne. 1) STOP 5
+ if (r2(1) .ne. 2.) STOP 6
+ if (d2 .ne. 20.) STOP 7
+ if (r2(4) .ne. 2.) STOP 8
+ if (r2(5) .ne. 2.) STOP 9
+ if (i2 .ne. 2) STOP 10
+ if (r3(1) .ne. 3.) STOP 11
+ if (d3 .ne. 30.) STOP 12
+ if (r3(4) .ne. 3.) STOP 13
+ if (r3(5) .ne. 3.) STOP 14
+ if (i3 .ne. 3) STOP 15
+
+ end
+
Index: Fortran/gfortran/regression/g77/980628-9.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980628-9.f
@@ -0,0 +1,58 @@
+c { dg-do run }
+c { dg-options "-std=gnu" }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+
+ character c1(11), c2(11), c3(11)
+ real r1, r2, r3
+ character c4, c5, c6
+ equivalence (r1, c1(2))
+ equivalence (r2, c2(2))
+ equivalence (r3, c3(2))
+
+ c1(1) = '1'
+ r1 = 1.
+ c1(11) = '1'
+ c4 = '4'
+ c2(1) = '2'
+ r2 = 2.
+ c2(11) = '2'
+ c5 = '5'
+ c3(1) = '3'
+ r3 = 3.
+ c3(11) = '3'
+ c6 = '6'
+
+ call x (c1, r1, c2, r2, c3, r3, c4, c5, c6)
+
+ end
+
+ subroutine x (c1, r1, c2, r2, c3, r3, c4, c5, c6)
+ implicit none
+
+ character c1(11), c2(11), c3(11)
+ real r1, r2, r3
+ character c4, c5, c6
+
+ if (c1(1) .ne. '1') STOP 1
+ if (r1 .ne. 1.) STOP 2
+ if (c1(11) .ne. '1') STOP 3
+ if (c4 .ne. '4') STOP 4
+ if (c2(1) .ne. '2') STOP 5
+ if (r2 .ne. 2.) STOP 6
+ if (c2(11) .ne. '2') STOP 7
+ if (c5 .ne. '5') STOP 8
+ if (c3(1) .ne. '3') STOP 9
+ if (r3 .ne. 3.) STOP 10
+ if (c3(11) .ne. '3') STOP 11
+ if (c6 .ne. '6') STOP 12
+
+ end
+
Index: Fortran/gfortran/regression/g77/980701-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980701-0.f
@@ -0,0 +1,73 @@
+c { dg-do run }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ real s1(2), s2(2), s3(2)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+ equivalence (r1, s1(2))
+ equivalence (d1, r1(2))
+ equivalence (r2, s2(2))
+ equivalence (d2, r2(2))
+ equivalence (r3, s3(2))
+ equivalence (d3, r3(2))
+
+ s1(1) = 1.
+ r1(1) = 1.
+ d1 = 10.
+ r1(4) = 1.
+ r1(5) = 1.
+ i1 = 1
+ s2(1) = 2.
+ r2(1) = 2.
+ d2 = 20.
+ r2(4) = 2.
+ r2(5) = 2.
+ i2 = 2
+ s3(1) = 3.
+ r3(1) = 3.
+ d3 = 30.
+ r3(4) = 3.
+ r3(5) = 3.
+ i3 = 3
+
+ call x (s1, r1, d1, i1, s2, r2, d2, i2, s3, r3, d3, i3)
+
+ end
+
+ subroutine x (s1, r1, d1, i1, s2, r2, d2, i2, s3, r3, d3, i3)
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ real s1(2), s2(2), s3(2)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+
+ if (s1(1) .ne. 1.) STOP 1
+ if (r1(1) .ne. 1.) STOP 2
+ if (d1 .ne. 10.) STOP 3
+ if (r1(4) .ne. 1.) STOP 4
+ if (r1(5) .ne. 1.) STOP 5
+ if (i1 .ne. 1) STOP 6
+ if (s2(1) .ne. 2.) STOP 7
+ if (r2(1) .ne. 2.) STOP 8
+ if (d2 .ne. 20.) STOP 9
+ if (r2(4) .ne. 2.) STOP 10
+ if (r2(5) .ne. 2.) STOP 11
+ if (i2 .ne. 2) STOP 12
+ if (s3(1) .ne. 3.) STOP 13
+ if (r3(1) .ne. 3.) STOP 14
+ if (d3 .ne. 30.) STOP 15
+ if (r3(4) .ne. 3.) STOP 16
+ if (r3(5) .ne. 3.) STOP 17
+ if (i3 .ne. 3) STOP 18
+
+ end
Index: Fortran/gfortran/regression/g77/980701-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980701-1.f
@@ -0,0 +1,73 @@
+c { dg-do run }
+* g77 0.5.23 and previous had bugs involving too little space
+* allocated for EQUIVALENCE and COMMON areas needing initial
+* padding to meet alignment requirements of the system.
+
+ call subr
+ end
+
+ subroutine subr
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ real s1(2), s2(2), s3(2)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+ equivalence (d1, r1(2))
+ equivalence (r1, s1(2))
+ equivalence (d2, r2(2))
+ equivalence (r2, s2(2))
+ equivalence (d3, r3(2))
+ equivalence (r3, s3(2))
+
+ s1(1) = 1.
+ r1(1) = 1.
+ d1 = 10.
+ r1(4) = 1.
+ r1(5) = 1.
+ i1 = 1
+ s2(1) = 2.
+ r2(1) = 2.
+ d2 = 20.
+ r2(4) = 2.
+ r2(5) = 2.
+ i2 = 2
+ s3(1) = 3.
+ r3(1) = 3.
+ d3 = 30.
+ r3(4) = 3.
+ r3(5) = 3.
+ i3 = 3
+
+ call x (s1, r1, d1, i1, s2, r2, d2, i2, s3, r3, d3, i3)
+
+ end
+
+ subroutine x (s1, r1, d1, i1, s2, r2, d2, i2, s3, r3, d3, i3)
+ implicit none
+
+ real r1(5), r2(5), r3(5)
+ real s1(2), s2(2), s3(2)
+ double precision d1, d2, d3
+ integer i1, i2, i3
+
+ if (s1(1) .ne. 1.) STOP 1
+ if (r1(1) .ne. 1.) STOP 2
+ if (d1 .ne. 10.) STOP 3
+ if (r1(4) .ne. 1.) STOP 4
+ if (r1(5) .ne. 1.) STOP 5
+ if (i1 .ne. 1) STOP 6
+ if (s2(1) .ne. 2.) STOP 7
+ if (r2(1) .ne. 2.) STOP 8
+ if (d2 .ne. 20.) STOP 9
+ if (r2(4) .ne. 2.) STOP 10
+ if (r2(5) .ne. 2.) STOP 11
+ if (i2 .ne. 2) STOP 12
+ if (s3(1) .ne. 3.) STOP 13
+ if (r3(1) .ne. 3.) STOP 14
+ if (d3 .ne. 30.) STOP 15
+ if (r3(4) .ne. 3.) STOP 16
+ if (r3(5) .ne. 3.) STOP 17
+ if (i3 .ne. 3) STOP 18
+
+ end
Index: Fortran/gfortran/regression/g77/980729-0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/980729-0.f
@@ -0,0 +1,6 @@
+c { dg-do compile }
+c Got ICE on Alpha only with -mieee (currently not tested).
+c Fixed by rth 1998-07-30 alpha.md change.
+ subroutine a(b,c)
+ b = max(b,c)
+ end
Index: Fortran/gfortran/regression/g77/981117-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/981117-1.f
@@ -0,0 +1,24 @@
+c { dg-do compile }
+* egcs-bugs:
+* From: Martin Kahlert
+* Subject: ICE in g77 from egcs-19981109
+* Message-Id: <199811101134.MAA29838@keksy.mchp.siemens.de>
+
+* As of 1998-11-17, fails -O2 -fomit-frame-pointer with
+* egcs/gcc/testsuite/g77.f-torture/compile/981117-1.f:8: internal error--insn does not satisfy its constraints:
+* (insn 31 83 32 (set (reg:SF 8 %st(0))
+* (mult:SF (reg:SF 8 %st(0))
+* (const_double:SF (mem/u:SF (symbol_ref/u:SI ("*.LC1")) 0) 0 0 1073643520))) 350 {strlensi-3} (nil)
+* (nil))
+* ../../egcs/gcc/toplev.c:1390: Internal compiler error in function fatal_insn
+
+* Fixed sometime before 1998-11-21 -- don't know by which change.
+
+ SUBROUTINE SSPTRD
+ PARAMETER (HALF = 0.5 )
+ DO I = 1, N
+ CALL SSPMV(TAUI)
+ ALPHA = -HALF*TAUI
+ CALL SAXPY(ALPHA)
+ ENDDO
+ END
Index: Fortran/gfortran/regression/g77/990115-1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/990115-1.f
@@ -0,0 +1,12 @@
+c { dg-do compile }
+C Derived from lapack
+ SUBROUTINE ZGELSX( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
+ $ WORK, RWORK, INFO )
+ COMPLEX(kind=8) WORK( * )
+c Following declaration added on transfer to gfortran testsuite.
+c It is present in original lapack source
+ integer rank
+ DO 20 I = 1, RANK
+ WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )
+ 20 CONTINUE
+ END
Index: Fortran/gfortran/regression/g77/README
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/README
@@ -0,0 +1,208 @@
+The g77 testsuite is being transferred to the gfortran testsuite.
+This file documents the status of each test case.
+
+ Y Test has been transferred.
+ Y XFAIL This test has been transferred but fails
+ N This feature will not be supported by gfortran.
+ F This test fails with gfortran. Not transferred (yet).
+ ? We looked at this case, but haven't decided.
+
+Directory g77.dg
+
+12632.f Y
+20010216-1.f Y
+7388.f Y
+f77-edit-apostrophe-out.f Y
+f77-edit-colon-out.f Y
+f77-edit-h-out.f Y
+f77-edit-i-in.f Y
+f77-edit-i-out.f Y
+f77-edit-s-out.f Y XFAIL PR 16434
+f77-edit-slash-out.f Y
+f77-edit-t-in.f Y XFAIL PR 16436
+f77-edit-t-out.f Y
+f77-edit-x-out.f Y XFAIL PR 16435
+fbackslash.f ?
+fcase-preserve.f ?
+ff90-1.f ?
+ffixed-form-1.f Y
+ffixed-form-2.f Y
+ffixed-line-length-0.f Y
+ffixed-line-length-132.f Y
+ffixed-line-length-7.f F PR 16465
+ffixed-line-length-72.f Y
+ffixed-line-length-none.f Y
+ffree-form-1.f Y
+ffree-form-2.f Y
+ffree-form-3.f Y
+fno-backslash.f ?
+fno-f90-1.f ?
+fno-fixed-form-1.f ?
+fno-onetrip.f ?
+fno-typeless-boz.f ?
+fno-underscoring.f Y
+fno-vxt-1.f ?
+fonetrip.f ?
+ftypeless-boz.f ?
+fugly-assumed.f ?
+funderscoring.f Y
+fvxt-1.f ?
+pr3743-1.f ?
+pr3743-2.f ?
+pr3743-3.f ?
+pr3743-4.f ?
+pr5473.f ?
+pr9258.f Y
+strlen0.f Y
+
+
+Directory g77.dg/bprob
+g77-bprob-1.f
+
+
+Directory g77.dg/gcov
+gcov-1.f
+
+Directory g77.f-torture/compile
+12002.f Y
+13060.f Y
+19990218-0.f Y
+19990305-0.f Y
+19990419-0.f Y
+19990502-0.f Y
+19990502-1.f Y
+19990525-0.f Y
+19990826-1.f Y
+19990826-3.f Y
+19990905-0.f Y XFAIL PR 16511
+19990905-2.f Y
+20000412-1.f Y
+20000511-1.f Y
+20000511-2.f Y
+20000518.f Y
+20000601-1.f Y
+20000601-2.f Y
+20000629-1.f Y
+20000630-2.f Y
+20010115.f Y
+20010321-1.f Y
+20010426.f Y
+20010519-1.f Y Add dg-warnings for ASSIGN
+20020307-1.f Y
+20030115-1.f Y Add dg-warnings for ASSIGN
+20030326-1.f Y
+8485.f Y
+960317-1.f Y
+970125-0.f Y Add dg-excess-errors. Investigate.later.
+970915-0.f Y
+980310-1.f Y
+980310-2.f Y
+980310-3.f Y
+980310-4.f Y
+980310-6.f Y
+980310-7.f Y
+980310-8.f Y
+980419-2.f Y
+980424-0.f Y
+980427-0.f Y
+980519-2.f Y Modify slightly
+980729-0.f Y
+981117-1.f Y
+990115-1.f Y Declare variable RANK
+alpha1.f Y Work around PR 16508 and PR 16509
+toon_1.f Y
+xformat.f Y Add dg-warning for extension
+cpp.F Y
+cpp2.F Y
+
+g77.f-torture/execute
+10197.f & 10197.x
+13037.f Y
+1832.f Y
+19981119-0.f Y
+19990313-0.f Y
+19990313-1.f Y
+19990313-2.f Y
+19990313-3.f Y
+19990325-0.f F Execution failure
+19990325-1.f F Execution failure
+19990419-1.f Y
+19990826-0.f Y
+19990826-2.f Y
+20000503-1.f Y
+20001111.f Y
+20001201.f & 20001201.x
+20010116.f Y
+20010426.f renamed 20010426-1.f Y
+20010430.f Y
+20010610.f Y
+5122.f - Assembler failure
+6177.f Y
+6367.f & 6367.x
+947.f Y
+970625-2.f Y Add dg-warnings and declare variables
+970816-3.f Y
+971102-1.f Y
+980520-1.f Y
+980628-0.f Y
+980628-1.f Y
+980628-10.f Y
+980628-2.f Y
+980628-3.f Y
+980628-4.f & 980628-4.x
+980628-5.f & 980628-5.x
+980628-6.f & 980628-6.x
+980628-7.f Y
+980628-8.f Y
+980628-9.f Y
+980701-0.f Y
+980701-1.f Y
+alpha2.f & alpha2.x
+auto0.f & auto0.x
+auto1.f & auto1.x
+cabs.f Y
+claus.f Y
+complex_1.f Y
+cpp.F (Renamed cpp3.F) Y
+cpp2.F - Compiler warnings
+dcomplex.f Y
+dnrm2.f Y Add dg-warning as required
+erfc.f Y
+exp.f Compiler warnings and fails
+f90-intrinsic-bit.f F 16581 Compile errors
+f90-intrinsic-mathematical.f Y
+f90-intrinsic-numeric.f Y
+int8421.f Y
+intrinsic-f2c-z.f F Execution fail
+intrinsic-unix-bessel.f Y
+intrinsic-unix-erf.f Y
+intrinsic-vax-cd.f F Execution fail
+intrinsic77.f F PR 16580 Compiler ICE
+io0.f & io0.x
+io1.f & io1.x
+labug1.f Y
+large_vec.f Y
+le.f Y
+select.f Lots of compiler warnings
+short.f Y
+u77-test.f & u77-test.x
+
+
+Directory g77.f-torture/noncompile
+19981216-0.f Y Accepted by gfortran
+19990218-1.f Y g77 issued warning.
+19990826-4.f ?
+19990905-1.f Y XFAIL 16520 gfortran ICE on invalid
+9263.f Y
+970626-2.f ?
+980615-0.f Y
+980616-0.f Y
+check0.f Y
+select_no_compile.f Y
+
+
+Copyright (C) 2004-2023 Free Software Foundation, Inc.
+
+Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved.
Index: Fortran/gfortran/regression/g77/alpha1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/alpha1.f
@@ -0,0 +1,27 @@
+c { dg-do compile }
+ REAL(kind=8) A,B,C
+ REAL(kind=4) RARRAY(19)
+ DATA RARRAY /19*-1/
+ INTEGER BOTTOM,RIGHT
+ INTEGER IARRAY(19)
+ DATA IARRAY /0,0,0,0,0,0,0,0,0,0,0,0,13,14,0,0,0,0,0/
+ EQUIVALENCE (RARRAY(13),BOTTOM),(RARRAY(14),RIGHT)
+C
+ IF(I.NE.0) call exit(1)
+C gcc: Internal compiler error: program f771 got fatal signal 11
+C at this point!
+ END
+
+! previously g77.ftorture/compile/alpha1.f with following alpha1.x
+!
+!# This test fails compilation in cross-endian environments, for example as
+!# below, with a "sorry" message.
+!
+!if { [ishost "i\[34567\]86-*-*"] } {
+! if { [istarget "mmix-knuth-mmixware"]
+! || [istarget "powerpc-*-*"] } {
+! set torture_compile_xfail [istarget]
+! }
+!}
+!
+!return 0
Index: Fortran/gfortran/regression/g77/cabs.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cabs.f
@@ -0,0 +1,15 @@
+c { dg-do run }
+ program cabs_1
+ complex z0
+ real r0
+ complex(kind=8) z1
+ real(kind=8) r1
+
+ z0 = cmplx(3.,4.)
+ r0 = cabs(z0)
+ if (r0 .ne. 5.) STOP 1
+
+ z1 = dcmplx(3.d0,4.d0)
+ r1 = zabs(z1)
+ if (r1 .ne. 5.d0) STOP 2
+ end
Index: Fortran/gfortran/regression/g77/check0.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/check0.f
@@ -0,0 +1,14 @@
+c { dg-do compile }
+c { dg-options "-std=legacy" }
+c
+CCC Abort fixed by:
+CCC1998-04-21 Jim Wilson
+CCC
+CCC * stmt.c (check_seenlabel): When search for line number note for
+CCC warning, handle case where there is no such note.
+ logical l(10)
+ integer i(10)
+ goto (10,20),l ! { dg-error "Selection expression in computed GOTO" }
+ goto (10,20),i ! { dg-error "Selection expression in computed GOTO" }
+ 10 stop
+ 20 end
Index: Fortran/gfortran/regression/g77/claus.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/claus.f
@@ -0,0 +1,14 @@
+c { dg-do run }
+ PROGRAM TEST
+ REAL AB(3)
+ do i=1,3
+ AB(i)=i
+ enddo
+ k=1
+ n=2
+ ind=k-n+2
+ if (ind /= 1) STOP 1
+ if (ab(ind) /= 1) STOP 2
+ if (k-n+2 /= 1) STOP 3
+ if (ab(k-n+2) /= 1) STOP 4
+ END
Index: Fortran/gfortran/regression/g77/complex_1.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/complex_1.f
@@ -0,0 +1,19 @@
+c { dg-do run }
+ program complex_1
+ complex z0, z1, z2
+
+ z0 = cmplx(0.,.5)
+ z1 = 1./z0
+ if (z1 .ne. cmplx(0.,-2)) STOP 1
+
+ z0 = 10.*z0
+ if (z0 .ne. cmplx(0.,5.)) STOP 2
+
+ z2 = cmplx(1.,2.)
+ z1 = z0/z2
+ if (z1 .ne. cmplx(2.,1.)) STOP 3
+
+ z1 = z0*z2
+ if (z1 .ne. cmplx(-10.,5.)) STOP 4
+ end
+
Index: Fortran/gfortran/regression/g77/cpp.F
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cpp.F
@@ -0,0 +1,10 @@
+c { dg-do compile }
+C When run through the C preprocessor, the indentation of the
+C CONTINUE line must not be mangled.
+ subroutine aap(a, n)
+ dimension a(n)
+ do 10 i = 1, n
+ a(i) = i
+ 10 continue
+ print *, a(1)
+ end
Index: Fortran/gfortran/regression/g77/cpp2.F
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cpp2.F
@@ -0,0 +1,8 @@
+c { dg-do compile }
+C The preprocessor must not introduce a newline after
+C the "a" when ARGUMENTS is expanded.
+
+#define ARGUMENTS a\
+
+ subroutine yada (ARGUMENTS)
+ end
Index: Fortran/gfortran/regression/g77/cpp3.F
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cpp3.F
@@ -0,0 +1,8 @@
+c { dg-do run }
+c { dg-options "-std=legacy" }
+c
+! Some versions of cpp will delete "//'World' as a C++ comment.
+ character*40 title
+ title = 'Hello '//'World'
+ if (title .ne. 'Hello World') STOP 1
+ end
Index: Fortran/gfortran/regression/g77/cpp4.F
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cpp4.F
@@ -0,0 +1,12 @@
+c { dg-do run }
+C The preprocessor must not mangle Hollerith constants
+C which contain apostrophes.
+ integer i
+ character(4) j
+ data i /4hbla'/
+ write (j, '(4a)') i
+ if (j .ne. "bla'") STOP 1
+ end
+
+ ! { dg-warning "Hollerith constant" "const" { target *-*-* } 6 }
+ ! { dg-warning "Conversion" "conversion" { target *-*-* } 6 }
Index: Fortran/gfortran/regression/g77/cpp5.h
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cpp5.h
@@ -0,0 +1,3 @@
+ FUNCTION FOO()
+#include "cpp5inc.h"
+ END FUNCTION
Index: Fortran/gfortran/regression/g77/cpp5.F
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cpp5.F
@@ -0,0 +1,4 @@
+ ! { dg-do run }
+#include "cpp5.h"
+ IF (FOO().NE.1) STOP 1
+ END
Index: Fortran/gfortran/regression/g77/cpp5inc.h
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cpp5inc.h
@@ -0,0 +1 @@
+ FOO = 1
Index: Fortran/gfortran/regression/g77/cpp6.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/cpp6.f
@@ -0,0 +1,20 @@
+# 1 "test.F"
+# 1 ""
+# 1 ""
+# 1 "test.F"
+! { dg-do compile }
+
+# 1 "A234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 1
+
+# 1 "B234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 1
+
+# 1 "C234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 1
+
+# 1 "D234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 1
+ PARAMETER (I=1)
+
+# 2 "C234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 2
+# 2 "B234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 2
+# 2 "A234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890" 2
+# 3 "test.F" 2
+ END
Index: Fortran/gfortran/regression/g77/dcomplex.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/dcomplex.f
@@ -0,0 +1,19 @@
+c { dg-do run }
+ program foo
+ complex(kind=8) z0, z1, z2
+
+ z0 = dcmplx(0.,.5)
+ z1 = 1./z0
+ if (z1 .ne. dcmplx(0.,-2)) STOP 1
+
+ z0 = 10.*z0
+ if (z0 .ne. dcmplx(0.,5.)) STOP 2
+
+ z2 = cmplx(1.,2.)
+ z1 = z0/z2
+ if (z1 .ne. dcmplx(2.,1.)) STOP 3
+
+ z1 = z0*z2
+ if (z1 .ne. dcmplx(-10.,5.)) STOP 4
+ end
+
Index: Fortran/gfortran/regression/g77/dnrm2.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/dnrm2.f
@@ -0,0 +1,76 @@
+c { dg-do run }
+c { dg-options "-fno-bounds-check" }
+CCC g77 0.5.21 `Actual Bugs':
+CCC * A code-generation bug afflicts Intel x86 targets when `-O2' is
+CCC specified compiling, for example, an old version of the `DNRM2'
+CCC routine. The x87 coprocessor stack is being somewhat mismanaged
+CCC in cases where assigned `GOTO' and `ASSIGN' are involved.
+CCC
+CCC Version 0.5.21 of `g77' contains an initial effort to fix the
+CCC problem, but this effort is incomplete, and a more complete fix is
+CCC planned for the next release.
+
+C Currently this test fails with (at least) `-O2 -funroll-loops' on
+C i586-unknown-linux-gnulibc1.
+
+C (This is actually an obsolete version of dnrm2 -- consult the
+c current Netlib BLAS.)
+
+ integer i
+ double precision a(1:100), dnrm2
+ do i=1,100
+ a(i)=0.D0
+ enddo
+ if (dnrm2(100,a,1) .ne. 0.0) STOP 1
+ end
+
+ double precision function dnrm2 ( n, dx, incx)
+ integer i, incx, ix, j, n, next
+ double precision dx(1), cutlo, cuthi, hitest, sum, xmax,zero,one
+ data zero, one /0.0d0, 1.0d0/
+ data cutlo, cuthi / 8.232d-11, 1.304d19 /
+ j = 0
+ if(n .gt. 0 .and. incx.gt.0) go to 10
+ dnrm2 = zero
+ go to 300
+ 10 assign 30 to next ! { dg-warning "ASSIGN" }
+ sum = zero
+ i = 1
+ ix = 1
+ 20 go to next,(30, 50, 70, 110) ! { dg-warning "Assigned GOTO" }
+ 30 if( dabs(dx(i)) .gt. cutlo) go to 85
+ assign 50 to next ! { dg-warning "ASSIGN" }
+ xmax = zero
+ 50 if( dx(i) .eq. zero) go to 200
+ if( dabs(dx(i)) .gt. cutlo) go to 85
+ assign 70 to next ! { dg-warning "ASSIGN" }
+ go to 105
+ 100 continue
+ ix = j
+ assign 110 to next ! { dg-warning "ASSIGN" }
+ sum = (sum / dx(i)) / dx(i)
+ 105 xmax = dabs(dx(i))
+ go to 115
+ 70 if( dabs(dx(i)) .gt. cutlo ) go to 75
+ 110 if( dabs(dx(i)) .le. xmax ) go to 115
+ sum = one + sum * (xmax / dx(i))**2
+ xmax = dabs(dx(i))
+ go to 200
+ 115 sum = sum + (dx(i)/xmax)**2
+ go to 200
+ 75 sum = (sum * xmax) * xmax
+ 85 hitest = cuthi/float( n )
+ do 95 j = ix,n
+ if(dabs(dx(i)) .ge. hitest) go to 100
+ sum = sum + dx(i)**2
+ i = i + incx
+ 95 continue
+ dnrm2 = dsqrt( sum )
+ go to 300
+ 200 continue
+ ix = ix + 1
+ i = i + incx
+ if( ix .le. n ) go to 20
+ dnrm2 = xmax * dsqrt(sum)
+ 300 continue
+ end
Index: Fortran/gfortran/regression/g77/erfc.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/erfc.f
@@ -0,0 +1,39 @@
+c { dg-do run }
+c============================================== test.f
+ real x, y
+ real(kind=8) x1, y1
+ x=0.
+ y = erfc(x)
+ if (y .ne. 1.) STOP 1
+
+ x=1.1
+ y = erfc(x)
+ if (abs(y - .1197949) .ge. 1.e-6) STOP 2
+
+c modified from x=10, y .gt. 1.5e-44 to avoid lack of -mieee on Alphas.
+ x=8
+ y = erfc(x)
+ if (y .gt. 1.2e-28) STOP 3
+
+ x1=0.
+ y1 = erfc(x1)
+ if (y1 .ne. 1.) STOP 4
+
+ x1=1.1d0
+ y1 = erfc(x1)
+ if (abs(y1 - .1197949d0) .ge. 1.d-6) STOP 5
+
+ x1=10
+ y1 = erfc(x1)
+ if (y1 .gt. 1.5d-44) STOP 6
+ end
+c=================================================
+!output:
+! 0. 1.875
+! 1.10000002 1.48958981
+! 10. 5.00220949E-06
+!
+!The values should be:
+!erfc(0)=1
+!erfc(1.1)= 0.1197949
+!erfc(10)<1.543115467311259E-044
Index: Fortran/gfortran/regression/g77/f77-edit-apostrophe-out.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/f77-edit-apostrophe-out.f
@@ -0,0 +1,21 @@
+C Test Fortran 77 apostrophe edit descriptor
+C (ANSI X3.9-1978 Section 13.5.1)
+C
+C Origin: David Billinghurst
+C
+C { dg-do run }
+C { dg-output "^" }
+ 10 format('abcde')
+ 20 format('and an apostrophe -''-')
+ 30 format('''a leading apostrophe')
+ 40 format('a trailing apostrophe''')
+ 50 format('''and all of the above -''-''')
+
+ write(*,10) ! { dg-output "abcde(\r*\n+)" }
+ write(*,20) ! { dg-output "and an apostrophe -'-(\r*\n+)" }
+ write(*,30) ! { dg-output "'a leading apostrophe(\r*\n+)" }
+ write(*,40) ! { dg-output "a trailing apostrophe'(\r*\n+)" }
+ write(*,50) ! { dg-output "'and all of the above -'-'(\r*\n+)" }
+
+C { dg-output "\$" }
+ end
Index: Fortran/gfortran/regression/g77/f77-edit-colon-out.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/f77-edit-colon-out.f
@@ -0,0 +1,9 @@
+C Test Fortran 77 colon edit descriptor
+C (ANSI X3.9-1978 Section 13.5.5)
+C
+C Origin: David Billinghurst
+C
+C { dg-do run }
+C { dg-output "^123(\r*\n+)45(\r*\n+)\$" }
+ write(*,'((3(I1:)))') (I,I=1,5)
+ end
Index: Fortran/gfortran/regression/g77/f77-edit-h-out.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/f77-edit-h-out.f
@@ -0,0 +1,14 @@
+C Test Fortran 77 H edit descriptor
+C (ANSI X3.9-1978 Section 13.5.2)
+C
+C Origin: David Billinghurst
+C
+C { dg-do run }
+C { dg-output "^" }
+ 10 format(1H1)
+ 20 format(6H 6)
+ write(*,10) ! { dg-output "1(\r*\n+)" }
+ write(*,20) ! { dg-output " 6(\r*\n+)" }
+ write(*,'(16H''apostrophe'' fun)') ! { dg-output "'apostrophe' fun(\r*\n+)" }
+C { dg-output "\$" }
+ end
Index: Fortran/gfortran/regression/g77/f77-edit-i-in.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/f77-edit-i-in.f
@@ -0,0 +1,24 @@
+C Test Fortran 77 I edit descriptor for input
+C (ANSI X3.9-1978 Section 13.5.9.1)
+C
+C Origin: David Billinghurst
+C
+C { dg-do run }
+C { dg-options "-std=legacy" }
+C
+
+ integer i,j
+ character*10 buf
+
+ write(buf,'(A)') '1 -1'
+
+ read(buf,'(I1)') i
+ if ( i.ne.1 ) STOP 1
+
+ read(buf,'(1X,I1)') i
+ if ( i.ne.0 ) STOP 2
+
+ read(buf,'(1X,I1,1X,I2)') i,j
+ if ( i.ne.0 .and. j.ne.-1 ) STOP 3
+
+ end
Index: Fortran/gfortran/regression/g77/f77-edit-i-out.f
===================================================================
--- /dev/null
+++ Fortran/gfortran/regression/g77/f77-edit-i-out.f
@@ -0,0 +1,26 @@
+C Test Fortran 77 I edit descriptor for output
+C (ANSI X3.9-1978 Section 13.5.9.1)
+C
+C Origin: David Billinghurst