Files
clang-p2996/flang/test/Semantics/implicit11.f90
Tim Keith b8bfe3586e [flang] Fix bug accessing implicit variable in specification expression
A specification expression can reference an implicitly declared variable
in the host procedure. Because we have to process specification parts
before execution parts, this may be the first time we encounter the
variable. We were assuming the variable was implicitly declared in the
scope where it was encountered, leading to an error because local
variables may not be referenced in specification expressions.

The fix is to tentatively create the implicit variable in the host
procedure because that is the only way the specification expression can
be valid. We mark it with the flag `ImplicitOrError` to indicate that
either it must be implicitly defined in the host (by being mentioned in
the execution part) or else its use turned out to be an error.
We need to apply the implicit type rules of the host, which requires
some changes to implicit typing.

Variables in common blocks are allowed to appear in specification expressions
(because they are not locals) but the common block definition may not appear
until after their use. To handle this we create common block symbols and object
entities for each common block object during the `PreSpecificationConstruct`
pass. This allows us to remove the corresponding code in the main visitor and
`commonBlockInfo_.curr`. The change in order of processing causes some
different error messages to be emitted.

Some cleanup is included with this change:
- In `ExpressionAnalyzer`, if an unresolved name is encountered but
  no error has been reported, emit an internal error.
- Change `ImplicitRulesVisitor` to hide the `ImplicitRules` object
  that implements it. Change the interface to pass in names rather
  than having to get the first character of the name.
- Change `DeclareObjectEntity` to have the `attrs` argument default
  to an empty set; that is the typical case.
- In `Pre(parser::SpecificationPart)` use "structured bindings" to
  give names to the pieces that make up a specification-part.
- Enhance `parser::Unwrap` to unwrap `Statement` and `UnlabeledStatement`
  and make use of that in PreSpecificationConstruct.

Differential Revision: https://reviews.llvm.org/D86322
2020-08-24 12:53:46 -07:00

62 lines
1.1 KiB
Fortran

! RUN: %S/test_errors.sh %s %t %f18
! Test use of implicitly declared variable in specification expression
subroutine s1()
m = 1
contains
subroutine s1a()
implicit none
!ERROR: No explicit type declared for 'n'
real :: a(m, n)
end
subroutine s1b()
!ERROR: Implicitly typed local entity 'n' not allowed in specification expression
real :: a(m, n)
end
end
subroutine s2()
type :: t(m, n)
integer, len :: m
integer, len :: n
end type
n = 1
contains
subroutine s2a()
!ERROR: Implicitly typed local entity 'm' not allowed in specification expression
type(t(m, n)) :: a
end
subroutine s2b()
implicit none
!ERROR: No explicit type declared for 'm'
character(m) :: a
end
end
subroutine s3()
m = 1
contains
subroutine s3a()
implicit none
real :: a(m, n)
!ERROR: No explicit type declared for 'n'
common n
end
subroutine s3b()
! n is okay here because it is in a common block
real :: a(m, n)
common n
end
end
subroutine s4()
implicit none
contains
subroutine s4a()
!ERROR: No explicit type declared for 'n'
real :: a(n)
end
end