Files
clang-p2996/flang/test/Semantics/resolve42.f90
Jean Perier 2c8cb9acb5 [flang] Handle common block with different sizes in same file
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
2022-04-29 14:52:47 +02:00

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