forked from OSchip/llvm-project
[flang] Check for attributes specific to dummy arguments
We were not checking that attributes that are supposed to be specific to dummy arguments were not being used for local entities. I added the checks along with tests for them. After implementing these new checks, I found that one of the tests in separate-mp02.f90 was erroneous, and I fixed it. Differential Revision: https://reviews.llvm.org/D101126
This commit is contained in:
parent
b2bb13a761
commit
f9c0859e96
|
@ -490,6 +490,14 @@ void CheckHelper::CheckObjectEntity(
|
|||
"non-POINTER dummy argument of pure subroutine must have INTENT() or VALUE attribute"_err_en_US);
|
||||
}
|
||||
}
|
||||
} else if (symbol.attrs().test(Attr::INTENT_IN) ||
|
||||
symbol.attrs().test(Attr::INTENT_OUT) ||
|
||||
symbol.attrs().test(Attr::INTENT_INOUT)) {
|
||||
messages_.Say("INTENT attributes may apply only to a dummy "
|
||||
"argument"_err_en_US); // C843
|
||||
} else if (IsOptional(symbol)) {
|
||||
messages_.Say("OPTIONAL attribute may apply only to a dummy "
|
||||
"argument"_err_en_US); // C849
|
||||
}
|
||||
if (IsStaticallyInitialized(symbol, true /* ignore DATA inits */)) { // C808
|
||||
CheckPointerInitialization(symbol);
|
||||
|
@ -618,8 +626,9 @@ void CheckHelper::CheckArraySpec(
|
|||
} else if (isAssumedRank) { // C837
|
||||
msg = "Assumed-rank array '%s' must be a dummy argument"_err_en_US;
|
||||
} else if (isImplied) {
|
||||
if (!IsNamedConstant(symbol)) { // C836
|
||||
msg = "Implied-shape array '%s' must be a named constant"_err_en_US;
|
||||
if (!IsNamedConstant(symbol)) { // C835, C836
|
||||
msg = "Implied-shape array '%s' must be a named constant or a "
|
||||
"dummy argument"_err_en_US;
|
||||
}
|
||||
} else if (IsNamedConstant(symbol)) {
|
||||
if (!isExplicit && !isImplied) {
|
||||
|
@ -664,6 +673,14 @@ void CheckHelper::CheckProcEntity(
|
|||
// function SIN as an actual argument.
|
||||
messages_.Say("A dummy procedure may not be ELEMENTAL"_err_en_US);
|
||||
}
|
||||
} else if (symbol.attrs().test(Attr::INTENT_IN) ||
|
||||
symbol.attrs().test(Attr::INTENT_OUT) ||
|
||||
symbol.attrs().test(Attr::INTENT_INOUT)) {
|
||||
messages_.Say("INTENT attributes may apply only to a dummy "
|
||||
"argument"_err_en_US); // C843
|
||||
} else if (IsOptional(symbol)) {
|
||||
messages_.Say("OPTIONAL attribute may apply only to a dummy "
|
||||
"argument"_err_en_US); // C849
|
||||
} else if (symbol.owner().IsDerivedType()) {
|
||||
if (!symbol.attrs().test(Attr::POINTER)) { // C756
|
||||
const auto &name{symbol.name()};
|
||||
|
|
|
@ -27,8 +27,8 @@ end
|
|||
subroutine s3(a, b)
|
||||
real :: a(*)
|
||||
!ERROR: Dummy array argument 'b' may not have implied shape
|
||||
real :: b(*,*) ! C836
|
||||
!ERROR: Implied-shape array 'c' must be a named constant
|
||||
real :: b(*,*) ! C835, C836
|
||||
!ERROR: Implied-shape array 'c' must be a named constant or a dummy argument
|
||||
real :: c(*) ! C836
|
||||
!ERROR: Named constant 'd' array must have constant or implied shape
|
||||
integer, parameter :: d(:) = [1, 2, 3]
|
||||
|
@ -56,3 +56,25 @@ subroutine s5()
|
|||
allocatable :: a
|
||||
allocatable :: b
|
||||
end subroutine
|
||||
|
||||
subroutine s6()
|
||||
!C835 An object whose array bounds are specified by an
|
||||
! implied-shape-or-assumed-size-spec shall be a dummy data object or a named
|
||||
! constant.
|
||||
!
|
||||
!C843 An entity with the INTENT attribute shall be a dummy data object or a
|
||||
! dummy procedure pointer.
|
||||
!
|
||||
!C849 An entity with the OPTIONAL attribute shall be a dummy argument.
|
||||
|
||||
!ERROR: Implied-shape array 'local1' must be a named constant or a dummy argument
|
||||
real, dimension (*) :: local1
|
||||
!ERROR: INTENT attributes may apply only to a dummy argument
|
||||
real, intent(in) :: local2
|
||||
!ERROR: INTENT attributes may apply only to a dummy argument
|
||||
procedure(), intent(in) :: p1
|
||||
!ERROR: OPTIONAL attribute may apply only to a dummy argument
|
||||
real, optional :: local3
|
||||
!ERROR: OPTIONAL attribute may apply only to a dummy argument
|
||||
procedure(), optional :: p2
|
||||
end subroutine
|
||||
|
|
|
@ -109,10 +109,10 @@ contains
|
|||
real, intent(out) :: y
|
||||
real :: z
|
||||
end
|
||||
!ERROR: Dummy argument name 'z' does not match corresponding name 'y' in interface body
|
||||
module subroutine s2(x, z)
|
||||
real, intent(in) :: x
|
||||
real, intent(out) :: y
|
||||
!ERROR: Dummy argument name 'z' does not match corresponding name 'y' in interface body
|
||||
real, intent(out) :: z
|
||||
end
|
||||
module subroutine s3(x, y)
|
||||
!ERROR: Dummy argument 'x' is a procedure; the corresponding argument in the interface body is not
|
||||
|
|
Loading…
Reference in New Issue