Semantics is not preventing a named common block to appear with different size in a same file (named common block should always have the same storage size (see Fortran 2018 8.10.2.5), but it is a common extension to accept different sizes). Lowering was not coping with this well, since it just use the first common block appearance, starting with BLOCK DATAs to define common blocks (this also was an issue with the blank common block, which can legally appear with different size in different scoping units). Semantics is also not preventing named common from being initialized outside of a BLOCK DATA, and lowering was dealing badly with this, since it only gave an initial value to common blocks Globals if the first common block appearance, starting with BLOCK DATAs had an initial value. Semantics is also allowing blank common to be initialized, while lowering was assuming this would never happen, and was never creating an initial value for it. Lastly, semantics was not complaining if a COMMON block was initialized in several scoping unit in a same file, while lowering can only generate one of these initial value. To fix this, add a structure to keep track of COMMON block properties (biggest size, and initial value if any) at the Program level. Once the size of a common block appearance is know, the common block appearance is checked against this information. It allows semantics to emit an error in case of multiple initialization in different scopes of a same common block, and to warn in case named common blocks appears with different sizes. Lastly, this allows lowering to use the Program level info about common blocks to emit the right GlobalOp for a Common Block, regardless of the COMMON Block appearances order: It emits a GlobalOp with the biggest size, whose lowest bytes are initialized with the initial value if any is given in a scope where the common block appears. Lowering is updated to go emit the common blocks before anything else so that the related GlobalOps are available when lowering the scopes where common block appear. It is also updated to not assume that blank common are never initialized. Differential Revision: https://reviews.llvm.org/D124622
115 lines
2.5 KiB
Fortran
115 lines
2.5 KiB
Fortran
! RUN: %python %S/test_errors.py %s %flang_fc1
|
|
subroutine s1
|
|
!ERROR: Array 'z' without ALLOCATABLE or POINTER attribute must have explicit shape
|
|
common x, y(4), z(:)
|
|
end
|
|
|
|
subroutine s2
|
|
common /c1/ x, y, z
|
|
!ERROR: 'y' is already in a COMMON block
|
|
common y
|
|
end
|
|
|
|
subroutine s3
|
|
!ERROR: 'x' may not be a procedure as it is in a COMMON block
|
|
procedure(real) :: x
|
|
common x
|
|
common y
|
|
!ERROR: 'y' may not be a procedure as it is in a COMMON block
|
|
procedure(real) :: y
|
|
end
|
|
|
|
subroutine s5
|
|
integer x(2)
|
|
!ERROR: The dimensions of 'x' have already been declared
|
|
common x(4), y(4)
|
|
!ERROR: The dimensions of 'y' have already been declared
|
|
real y(2)
|
|
end
|
|
|
|
function f6(x) result(r)
|
|
!ERROR: Dummy argument 'x' may not appear in a COMMON block
|
|
!ERROR: ALLOCATABLE object 'y' may not appear in a COMMON block
|
|
common x,y,z
|
|
allocatable y
|
|
!ERROR: Function result 'r' may not appear in a COMMON block
|
|
common r
|
|
end
|
|
|
|
module m7
|
|
!ERROR: Variable 'w' with BIND attribute may not appear in a COMMON block
|
|
!ERROR: Variable 'z' with BIND attribute may not appear in a COMMON block
|
|
common w,z
|
|
integer, bind(c) :: z
|
|
integer, bind(c,name="w") :: w
|
|
end
|
|
|
|
module m8
|
|
type t
|
|
end type
|
|
class(*), pointer :: x
|
|
!ERROR: Unlimited polymorphic pointer 'x' may not appear in a COMMON block
|
|
!ERROR: Unlimited polymorphic pointer 'y' may not appear in a COMMON block
|
|
common x, y
|
|
class(*), pointer :: y
|
|
end
|
|
|
|
module m9
|
|
integer x
|
|
end
|
|
subroutine s9
|
|
use m9
|
|
!ERROR: 'x' is use-associated from module 'm9' and cannot be re-declared
|
|
common x
|
|
end
|
|
|
|
module m10
|
|
type t
|
|
end type
|
|
type(t) :: x
|
|
!ERROR: Derived type 'x' in COMMON block must have the BIND or SEQUENCE attribute
|
|
common x
|
|
end
|
|
|
|
module m11
|
|
type t1
|
|
sequence
|
|
integer, allocatable :: a
|
|
end type
|
|
type t2
|
|
sequence
|
|
type(t1) :: b
|
|
integer:: c
|
|
end type
|
|
type(t2) :: x2
|
|
!ERROR: Derived type variable 'x2' may not appear in a COMMON block due to ALLOCATABLE component
|
|
common /c2/ x2
|
|
end
|
|
|
|
module m12
|
|
type t1
|
|
sequence
|
|
integer :: a = 123
|
|
end type
|
|
type t2
|
|
sequence
|
|
type(t1) :: b
|
|
integer:: c
|
|
end type
|
|
type(t2) :: x2
|
|
!ERROR: Derived type variable 'x2' may not appear in a COMMON block due to component with default initialization
|
|
common /c3/ x2
|
|
end
|
|
|
|
subroutine s13
|
|
block
|
|
!ERROR: COMMON statement is not allowed in a BLOCK construct
|
|
common x
|
|
end block
|
|
end
|
|
|
|
subroutine s14
|
|
!ERROR: 'c' appears as a COMMON block in a BIND statement but not in a COMMON statement
|
|
bind(c) :: /c/
|
|
end
|