[flang] Catch attempts to copy pointers in allocatables in PURE

In a pure context, a pointer acquired from an INTENT(IN) dummy argument
may not be copied.  Catch the case in which the pointer is a component
of an allocatable component at some depth of nesting.

(This patch adds a new component iterator kind that is a variant of
a potential subobject component iterator; it visits all potential
subobject components, plus pointers, into which it does not descend.)

Differential Revision: https://reviews.llvm.org/D139161
This commit is contained in:
Peter Klausler
2022-11-17 16:30:49 -08:00
parent e31160155e
commit 962863d988
4 changed files with 31 additions and 35 deletions

View File

@@ -98,9 +98,9 @@ static std::optional<std::string> GetPointerComponentDesignatorName(
const SomeExpr &expr) {
if (const auto *derived{
evaluate::GetDerivedTypeSpec(evaluate::DynamicType::From(expr))}) {
UltimateComponentIterator ultimates{*derived};
PotentialAndPointerComponentIterator potentials{*derived};
if (auto pointer{
std::find_if(ultimates.begin(), ultimates.end(), IsPointer)}) {
std::find_if(potentials.begin(), potentials.end(), IsPointer)}) {
return pointer.BuildResultDesignatorName();
}
}
@@ -116,7 +116,7 @@ bool CheckCopyabilityInPureScope(parser::ContextualMessages &messages,
if (auto pointer{GetPointerComponentDesignatorName(expr)}) {
evaluate::SayWithDeclaration(messages, *base,
"A pure subprogram may not copy the value of '%s' because it is %s"
" and has the POINTER component '%s'"_err_en_US,
" and has the POINTER potential subobject component '%s'"_err_en_US,
base->name(), why, *pointer);
return false;
}