[flang-commits] [flang] e9088e3 - [flang] When resolving a binding, allow for overriding
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Thu Dec 15 15:09:01 PST 2022
Author: Peter Klausler
Date: 2022-12-15T15:08:48-08:00
New Revision: e9088e3789bb695217e5a6b57bc4d4ca0510bf7b
URL: https://github.com/llvm/llvm-project/commit/e9088e3789bb695217e5a6b57bc4d4ca0510bf7b
DIFF: https://github.com/llvm/llvm-project/commit/e9088e3789bb695217e5a6b57bc4d4ca0510bf7b.diff
LOG: [flang] When resolving a binding, allow for overriding
In type-bound generic resolution, when the actual argument
is monomorphic, resolve the call to the target of the
most recent (i.e., least deeply inherited) override of
the binding, if any.
Differential Revision: https://reviews.llvm.org/D140127
Added:
Modified:
flang/lib/Semantics/expression.cpp
Removed:
################################################################################
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index f4a3eb653feef..daf763c440d2f 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -2071,6 +2071,7 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
}
if (auto *dtExpr{UnwrapExpr<Expr<SomeDerived>>(*base)}) {
if (sym->has<semantics::GenericDetails>()) {
+ auto dyType{dtExpr->GetType()};
AdjustActuals adjustment{
[&](const Symbol &proc, ActualArguments &actuals) {
if (!proc.attrs().test(semantics::Attr::NOPASS)) {
@@ -2082,6 +2083,15 @@ auto ExpressionAnalyzer::AnalyzeProcedureComponentRef(
sym = pair.first;
if (sym) {
// re-resolve the name to the specific binding
+ CHECK(sym->has<semantics::ProcBindingDetails>());
+ // Use the most recent override of the binding, if any
+ CHECK(dyType && dyType->category() == TypeCategory::Derived &&
+ !dyType->IsUnlimitedPolymorphic());
+ if (const Symbol *latest{
+ DEREF(dyType->GetDerivedTypeSpec().typeSymbol().scope())
+ .FindComponent(sym->name())}) {
+ sym = latest;
+ }
sc.component.symbol = const_cast<Symbol *>(sym);
} else {
EmitGenericResolutionError(
@@ -3834,14 +3844,14 @@ std::optional<ProcedureRef> ArgumentAnalyzer::GetDefinedAssignmentProc() {
context_.EmitGenericResolutionError(*symbol, pair.second, true);
}
}
- for (std::size_t i{0}; i < actuals_.size(); ++i) {
+ for (std::size_t i{0}; !proc && i < actuals_.size(); ++i) {
const Symbol *generic{nullptr};
- if (const Symbol *specific{FindBoundOp(oprName, i, generic, true)}) {
+ if (const Symbol *binding{FindBoundOp(oprName, i, generic, true)}) {
if (const Symbol *resolution{
- GetBindingResolution(GetType(i), *specific)}) {
+ GetBindingResolution(GetType(i), *binding)}) {
proc = resolution;
} else {
- proc = specific;
+ proc = binding;
passedObjectIndex = i;
}
}
@@ -3924,23 +3934,30 @@ bool ArgumentAnalyzer::AreConformable() const {
const Symbol *ArgumentAnalyzer::FindBoundOp(parser::CharBlock oprName,
int passIndex, const Symbol *&generic, bool isSubroutine) {
const auto *type{GetDerivedTypeSpec(GetType(passIndex))};
- if (!type || !type->scope()) {
- return nullptr;
- }
- generic = type->scope()->FindComponent(oprName);
- if (!generic) {
- return nullptr;
- }
- ExpressionAnalyzer::AdjustActuals adjustment{
- [&](const Symbol &proc, ActualArguments &) {
- return passIndex == GetPassIndex(proc);
- }};
- auto pair{
- context_.ResolveGeneric(*generic, actuals_, adjustment, isSubroutine)};
- if (!pair.first) {
- context_.EmitGenericResolutionError(*generic, pair.second, isSubroutine);
+ const semantics::Scope *scope{type ? type->scope() : nullptr};
+ if (scope) {
+ // Use the original type definition's scope, since PDT
+ // instantiations don't have redundant copies of bindings or
+ // generics.
+ scope = DEREF(scope->derivedTypeSpec()).typeSymbol().scope();
+ }
+ generic = scope ? scope->FindComponent(oprName) : nullptr;
+ if (generic) {
+ ExpressionAnalyzer::AdjustActuals adjustment{
+ [&](const Symbol &proc, ActualArguments &) {
+ return passIndex == GetPassIndex(proc);
+ }};
+ auto pair{
+ context_.ResolveGeneric(*generic, actuals_, adjustment, isSubroutine)};
+ if (const Symbol *binding{pair.first}) {
+ CHECK(binding->has<semantics::ProcBindingDetails>());
+ // Use the most recent override of the binding, if any
+ return scope->FindComponent(binding->name());
+ } else {
+ context_.EmitGenericResolutionError(*generic, pair.second, isSubroutine);
+ }
}
- return pair.first;
+ return nullptr;
}
// If there is an implicit conversion between intrinsic types, make it explicit
More information about the flang-commits
mailing list