[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) { [&](const semantics::ProcBindingDetails &binding) {
if (auto result{CharacterizeProcedure( if (auto result{CharacterizeProcedure(
binding.symbol(), context, seenProcs)}) { 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)) { if (!symbol.attrs().test(semantics::Attr::NOPASS)) {
auto passName{binding.passName()}; auto passName{binding.passName()};
for (auto &dummy : result->dummyArguments) { for (auto &dummy : result->dummyArguments) {
if (!passName || dummy.name.c_str() == *passName) { if (!passName || dummy.name.c_str() == *passName) {
dummy.pass = true; dummy.pass = true;
return result; break;
} }
} }
DIE("PASS argument missing");
} }
return result; return result;
} else { } else {

View File

@ -1247,7 +1247,8 @@ bool IsElementalProcedure(const Symbol &original) {
IsElementalProcedure(*procInterface); IsElementalProcedure(*procInterface);
} }
} else if (const auto *details{symbol.detailsIf<ProcBindingDetails>()}) { } 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)) { } else if (!IsProcedure(symbol)) {
return false; return false;
} }

View File

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