[flang] Fix function call implicit typing after recent merge
Original-commit: flang-compiler/f18@f91779c79a Reviewed-on: https://github.com/flang-compiler/f18/pull/531 Tree-same-pre-rewrite: false
This commit is contained in:
parent
00e128e42a
commit
ba780030c7
|
@ -386,14 +386,21 @@ std::optional<Procedure> Procedure::Characterize(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.attrs.set(Procedure::Attr::ImplicitInterface);
|
result.attrs.set(Procedure::Attr::ImplicitInterface);
|
||||||
if (const semantics::DeclTypeSpec * type{interface.type()}) {
|
if (symbol.test(semantics::Symbol::Flag::Function)) {
|
||||||
if (auto resultType{DynamicType::From(*type)}) {
|
if (const semantics::DeclTypeSpec * type{interface.type()}) {
|
||||||
result.functionResult = FunctionResult{*resultType};
|
if (auto resultType{DynamicType::From(*type)}) {
|
||||||
|
result.functionResult = FunctionResult{*resultType};
|
||||||
|
} else {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// subroutine, not function
|
// subroutine, not function
|
||||||
|
if (interface.type() != nullptr) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetProcedureAttrs(result, symbol);
|
SetProcedureAttrs(result, symbol);
|
||||||
|
|
|
@ -1039,6 +1039,8 @@ public:
|
||||||
bool Pre(const parser::Submodule &) { DIE("unreachable"); }
|
bool Pre(const parser::Submodule &) { DIE("unreachable"); }
|
||||||
bool Pre(const parser::BlockData &) { DIE("unreachable"); }
|
bool Pre(const parser::BlockData &) { DIE("unreachable"); }
|
||||||
|
|
||||||
|
bool SetProcFlag(const parser::Name &, Symbol &, Symbol::Flag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Kind of procedure we are expecting to see in a ProcedureDesignator
|
// Kind of procedure we are expecting to see in a ProcedureDesignator
|
||||||
std::optional<Symbol::Flag> expectedProcFlag_;
|
std::optional<Symbol::Flag> expectedProcFlag_;
|
||||||
|
@ -1048,7 +1050,6 @@ private:
|
||||||
void CheckImport(const SourceName &, const SourceName &);
|
void CheckImport(const SourceName &, const SourceName &);
|
||||||
void HandleCall(Symbol::Flag, const parser::Call &);
|
void HandleCall(Symbol::Flag, const parser::Call &);
|
||||||
void HandleProcedureName(Symbol::Flag, const parser::Name &);
|
void HandleProcedureName(Symbol::Flag, const parser::Name &);
|
||||||
bool SetProcFlag(const parser::Name &, Symbol &, Symbol::Flag);
|
|
||||||
void ResolveExecutionParts(const ProgramTree &);
|
void ResolveExecutionParts(const ProgramTree &);
|
||||||
void AddSubpNames(const ProgramTree &);
|
void AddSubpNames(const ProgramTree &);
|
||||||
bool BeginScope(const ProgramTree &);
|
bool BeginScope(const ProgramTree &);
|
||||||
|
@ -1681,6 +1682,9 @@ static bool NeedsType(const Symbol &symbol) {
|
||||||
[](const EntityDetails &) { return true; },
|
[](const EntityDetails &) { return true; },
|
||||||
[](const ObjectEntityDetails &) { return true; },
|
[](const ObjectEntityDetails &) { return true; },
|
||||||
[](const AssocEntityDetails &) { return true; },
|
[](const AssocEntityDetails &) { return true; },
|
||||||
|
[&](const ProcEntityDetails &) {
|
||||||
|
return symbol.test(Symbol::Flag::Function);
|
||||||
|
},
|
||||||
[](const auto &) { return false; },
|
[](const auto &) { return false; },
|
||||||
},
|
},
|
||||||
symbol.details());
|
symbol.details());
|
||||||
|
@ -4861,11 +4865,12 @@ bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls to dummy procedures need to record that their symbols are known
|
// References to procedures need to record that their symbols are known
|
||||||
// to be procedures, so that they don't get converted to objects by default.
|
// to be procedures, so that they don't get converted to objects by default.
|
||||||
class ExecutionPartSkimmer {
|
class ExecutionPartSkimmer {
|
||||||
public:
|
public:
|
||||||
explicit ExecutionPartSkimmer(Scope &s) : scope_{s} {}
|
ExecutionPartSkimmer(ResolveNamesVisitor &resolver, Scope &s)
|
||||||
|
: resolver_{resolver}, scope_{s} {}
|
||||||
|
|
||||||
void Walk(const parser::ExecutionPart *exec) {
|
void Walk(const parser::ExecutionPart *exec) {
|
||||||
if (exec != nullptr) {
|
if (exec != nullptr) {
|
||||||
|
@ -4885,6 +4890,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void NoteCall(Symbol::Flag, const parser::Call &);
|
void NoteCall(Symbol::Flag, const parser::Call &);
|
||||||
|
|
||||||
|
ResolveNamesVisitor &resolver_;
|
||||||
Scope &scope_;
|
Scope &scope_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4894,10 +4900,11 @@ void ExecutionPartSkimmer::NoteCall(
|
||||||
if (const auto *name{std::get_if<parser::Name>(&designator.u)}) {
|
if (const auto *name{std::get_if<parser::Name>(&designator.u)}) {
|
||||||
if (Symbol * symbol{scope_.FindSymbol(name->source)}) {
|
if (Symbol * symbol{scope_.FindSymbol(name->source)}) {
|
||||||
if (auto *details{symbol->detailsIf<EntityDetails>()}) {
|
if (auto *details{symbol->detailsIf<EntityDetails>()}) {
|
||||||
if (details->isDummy()) {
|
if (resolver_.SetProcFlag(*name, *symbol, flag)) {
|
||||||
symbol->set_details(ProcEntityDetails{std::move(*details)});
|
symbol->set_details(ProcEntityDetails{std::move(*details)});
|
||||||
symbol->set(flag);
|
if (symbol->IsDummy()) {
|
||||||
symbol->attrs().set(Attr::EXTERNAL);
|
symbol->attrs().set(Attr::EXTERNAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4921,9 +4928,9 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
|
||||||
for (auto &child : node.children()) {
|
for (auto &child : node.children()) {
|
||||||
ResolveSpecificationParts(child);
|
ResolveSpecificationParts(child);
|
||||||
}
|
}
|
||||||
ExecutionPartSkimmer{scope}.Walk(node.exec());
|
ExecutionPartSkimmer{*this, scope}.Walk(node.exec());
|
||||||
PopScope();
|
PopScope();
|
||||||
// Ensure every object entity has a type:
|
// Ensure every object and function entity has a type.
|
||||||
for (auto &pair : *node.scope()) {
|
for (auto &pair : *node.scope()) {
|
||||||
ApplyImplicitRules(*pair.second);
|
ApplyImplicitRules(*pair.second);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue