forked from OSchip/llvm-project
[flang] Fix PURE check on procedure binding
A symbol that represents a procedure binding is PURE if the procedure it is bound to is PURE. Fix `IsPureProcedure` to check that. Make use of `IsPureProcedure` in `CheckSpecificationExprHelper`. Original-commit: flang-compiler/f18@c95f2eb4fb Reviewed-on: https://github.com/flang-compiler/f18/pull/849
This commit is contained in:
parent
293c7c28a8
commit
203627d3a5
|
@ -218,7 +218,7 @@ public:
|
|||
|
||||
template<typename T> Result operator()(const FunctionRef<T> &x) const {
|
||||
if (const auto *symbol{x.proc().GetSymbol()}) {
|
||||
if (!symbol->attrs().test(semantics::Attr::PURE)) {
|
||||
if (!semantics::IsPureProcedure(*symbol)) {
|
||||
return "reference to impure function '"s + symbol->name().ToString() +
|
||||
"'";
|
||||
}
|
||||
|
|
|
@ -242,8 +242,12 @@ bool IsPureProcedure(const Symbol &symbol) {
|
|||
// procedure component with a PURE interface
|
||||
return IsPureProcedure(*procInterface);
|
||||
}
|
||||
} else if (const auto *details{symbol.detailsIf<ProcBindingDetails>()}) {
|
||||
return IsPureProcedure(details->symbol());
|
||||
} else if (!IsProcedure(symbol)) {
|
||||
return false;
|
||||
}
|
||||
return symbol.attrs().test(Attr::PURE) && IsProcedure(symbol);
|
||||
return symbol.attrs().test(Attr::PURE);
|
||||
}
|
||||
|
||||
bool IsPureProcedure(const Scope &scope) {
|
||||
|
|
|
@ -18,12 +18,13 @@ module m
|
|||
|
||||
type :: t
|
||||
contains
|
||||
procedure, nopass :: tbp => pure
|
||||
procedure, nopass :: tbp_pure => pure
|
||||
procedure, nopass :: tbp_impure => impure
|
||||
end type
|
||||
type, extends(t) :: t2
|
||||
contains
|
||||
!ERROR: An overridden PURE type-bound procedure binding must also be PURE
|
||||
procedure, nopass :: tbp => impure ! 7.5.7.3
|
||||
procedure, nopass :: tbp_pure => impure ! 7.5.7.3
|
||||
end type
|
||||
|
||||
contains
|
||||
|
@ -51,4 +52,25 @@ module m
|
|||
a(j) = impure(j) ! C1139
|
||||
end do
|
||||
end subroutine
|
||||
subroutine test2
|
||||
type(t) :: x
|
||||
real :: a(x%tbp_pure(1)) ! ok
|
||||
!ERROR: Invalid specification expression: reference to impure function 'tbp_impure'
|
||||
real :: b(x%tbp_impure(1))
|
||||
forall (j=1:1)
|
||||
a(j) = x%tbp_pure(j) ! ok
|
||||
end forall
|
||||
forall (j=1:1)
|
||||
!ERROR: Impure procedure 'tbp_impure' may not be referenced in a FORALL
|
||||
a(j) = x%tbp_impure(j) ! C1037
|
||||
end forall
|
||||
do concurrent (j=1:1, x%tbp_pure(j) /= 0) ! ok
|
||||
a(j) = x%tbp_pure(j) ! ok
|
||||
end do
|
||||
!ERROR: Concurrent-header mask expression cannot reference an impure procedure
|
||||
do concurrent (j=1:1, x%tbp_impure(j) /= 0) ! C1121
|
||||
!ERROR: Call to an impure procedure component is not allowed in DO CONCURRENT
|
||||
a(j) = x%tbp_impure(j) ! C1139
|
||||
end do
|
||||
end subroutine
|
||||
end module
|
||||
|
|
Loading…
Reference in New Issue