[flang] Don't inherit ELEMENTAL attribute from intrinsics for TBP bindings

Type-bound procedure bindings that specify intrinsic procedures as their
interfaces should not acquire the ELEMENTAL attribute from the purposes
of compatibility checking between inherited bindings and their overrides
in extended derived types.

Differential Revision: https://reviews.llvm.org/D131104
This commit is contained in:
Peter Klausler 2022-07-27 13:15:24 -07:00
parent f53f2f232f
commit 5e8094bae5
3 changed files with 8 additions and 5 deletions

View File

@ -530,15 +530,17 @@ static std::optional<Procedure> CharacterizeProcedure(
[&](const semantics::ProcBindingDetails &binding) {
if (auto result{CharacterizeProcedure(
binding.symbol(), context, seenProcs)}) {
if (binding.symbol().attrs().test(semantics::Attr::INTRINSIC)) {
result->attrs.reset(Procedure::Attr::Elemental);
}
if (!symbol.attrs().test(semantics::Attr::NOPASS)) {
auto passName{binding.passName()};
for (auto &dummy : result->dummyArguments) {
if (!passName || dummy.name.c_str() == *passName) {
dummy.pass = true;
return result;
break;
}
}
DIE("PASS argument missing");
}
return result;
} else {

View File

@ -1247,7 +1247,8 @@ bool IsElementalProcedure(const Symbol &original) {
IsElementalProcedure(*procInterface);
}
} else if (const auto *details{symbol.detailsIf<ProcBindingDetails>()}) {
return IsElementalProcedure(details->symbol());
return !details->symbol().attrs().test(Attr::INTRINSIC) &&
IsElementalProcedure(details->symbol());
} else if (!IsProcedure(symbol)) {
return false;
}

View File

@ -1661,7 +1661,7 @@ void CheckHelper::CheckProcBinding(
return;
}
if (!IsElementalProcedure(binding.symbol()) &&
IsElementalProcedure(overriddenBinding->symbol())) {
IsElementalProcedure(*overridden)) {
SayWithDeclaration(*overridden,
"A type-bound procedure and its override must both, or neither, be ELEMENTAL"_err_en_US);
return;
@ -1674,7 +1674,7 @@ void CheckHelper::CheckProcBinding(
: "A passed-argument type-bound procedure may not override a NOPASS procedure"_err_en_US);
} else {
const auto *bindingChars{Characterize(binding.symbol())};
const auto *overriddenChars{Characterize(overriddenBinding->symbol())};
const auto *overriddenChars{Characterize(*overridden)};
if (bindingChars && overriddenChars) {
if (isNopass) {
if (!bindingChars->CanOverride(*overriddenChars, std::nullopt)) {