Skip to content

[flang] Emit "raw" name for procedure interface in module file #83915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion flang/include/flang/Semantics/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,8 +417,12 @@ class ProcEntityDetails : public EntityDetails, public WithPassArg {
ProcEntityDetails(ProcEntityDetails &&) = default;
ProcEntityDetails &operator=(const ProcEntityDetails &) = default;

const Symbol *rawProcInterface() const { return rawProcInterface_; }
const Symbol *procInterface() const { return procInterface_; }
void set_procInterface(const Symbol &sym) { procInterface_ = &sym; }
void set_procInterfaces(const Symbol &raw, const Symbol &resolved) {
rawProcInterface_ = &raw;
procInterface_ = &resolved;
}
inline bool HasExplicitInterface() const;

// Be advised: !init().has_value() => uninitialized pointer,
Expand All @@ -430,6 +434,7 @@ class ProcEntityDetails : public EntityDetails, public WithPassArg {
void set_isCUDAKernel(bool yes = true) { isCUDAKernel_ = yes; }

private:
const Symbol *rawProcInterface_{nullptr};
const Symbol *procInterface_{nullptr};
std::optional<const Symbol *> init_;
bool isCUDAKernel_{false};
Expand Down
4 changes: 1 addition & 3 deletions flang/lib/Semantics/check-declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1195,9 +1195,7 @@ void CheckHelper::CheckArraySpec(
void CheckHelper::CheckProcEntity(
const Symbol &symbol, const ProcEntityDetails &details) {
CheckSymbolType(symbol);
const Symbol *interface {
details.procInterface() ? &details.procInterface()->GetUltimate() : nullptr
};
const Symbol *interface{details.procInterface()};
if (details.isDummy()) {
if (!symbol.attrs().test(Attr::POINTER) && // C843
(symbol.attrs().test(Attr::INTENT_IN) ||
Expand Down
8 changes: 4 additions & 4 deletions flang/lib/Semantics/mod-file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -924,8 +924,8 @@ void ModFileWriter::PutProcEntity(llvm::raw_ostream &os, const Symbol &symbol) {
os, symbol,
[&]() {
os << "procedure(";
if (details.procInterface()) {
os << details.procInterface()->name();
if (details.rawProcInterface()) {
os << details.rawProcInterface()->name();
} else if (details.type()) {
PutType(os, *details.type());
}
Expand Down Expand Up @@ -1622,8 +1622,8 @@ void SubprogramSymbolCollector::DoSymbol(
}
},
[this](const ProcEntityDetails &details) {
if (details.procInterface()) {
DoSymbol(*details.procInterface());
if (details.rawProcInterface()) {
DoSymbol(*details.rawProcInterface());
} else {
DoType(details.type());
}
Expand Down
5 changes: 3 additions & 2 deletions flang/lib/Semantics/resolve-names-utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -845,8 +845,9 @@ void SymbolMapper::MapSymbolExprs(Symbol &symbol) {
},
[&](ProcEntityDetails &proc) {
if (const Symbol *
mappedSymbol{MapInterface(proc.procInterface())}) {
proc.set_procInterface(*mappedSymbol);
mappedSymbol{MapInterface(proc.rawProcInterface())}) {
proc.set_procInterfaces(
*mappedSymbol, BypassGeneric(mappedSymbol->GetUltimate()));
} else if (const DeclTypeSpec * mappedType{MapType(proc.type())}) {
proc.set_type(*mappedType);
}
Expand Down
16 changes: 8 additions & 8 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4983,7 +4983,8 @@ Symbol &DeclarationVisitor::DeclareProcEntity(
"The interface for procedure '%s' has already been declared"_err_en_US);
context().SetError(symbol);
} else if (interface) {
details->set_procInterface(*interface);
details->set_procInterfaces(
*interface, BypassGeneric(interface->GetUltimate()));
if (interface->test(Symbol::Flag::Function)) {
symbol.set(Symbol::Flag::Function);
} else if (interface->test(Symbol::Flag::Subroutine)) {
Expand Down Expand Up @@ -5658,10 +5659,10 @@ void DeclarationVisitor::Post(const parser::ProcInterface &x) {
}
void DeclarationVisitor::Post(const parser::ProcDecl &x) {
const auto &name{std::get<parser::Name>(x.t)};
const Symbol *procInterface{nullptr};
if (interfaceName_ && interfaceName_->symbol) {
procInterface = &BypassGeneric(*interfaceName_->symbol);
}
// Don't use BypassGeneric or GetUltimate on this symbol, they can
// lead to unusable names in module files.
const Symbol *procInterface{
interfaceName_ ? interfaceName_->symbol : nullptr};
auto attrs{HandleSaveName(name.source, GetAttrs())};
DerivedTypeDetails *dtDetails{nullptr};
if (Symbol * symbol{currScope().symbol()}) {
Expand Down Expand Up @@ -6624,10 +6625,9 @@ void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
if (const Symbol * symbol{name.symbol}) {
const Symbol &ultimate{symbol->GetUltimate()};
if (!context().HasError(*symbol) && !context().HasError(ultimate) &&
!ultimate.HasExplicitInterface()) {
!BypassGeneric(ultimate).HasExplicitInterface()) {
Say(name,
"'%s' must be an abstract interface or a procedure with "
"an explicit interface"_err_en_US,
"'%s' must be an abstract interface or a procedure with an explicit interface"_err_en_US,
symbol->name());
}
}
Expand Down
3 changes: 3 additions & 0 deletions flang/lib/Semantics/symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ llvm::raw_ostream &operator<<(
llvm::raw_ostream &operator<<(
llvm::raw_ostream &os, const ProcEntityDetails &x) {
if (x.procInterface_) {
if (x.rawProcInterface_ != x.procInterface_) {
os << ' ' << x.rawProcInterface_->name() << " ->";
}
os << ' ' << x.procInterface_->name();
} else {
DumpType(os, x.type());
Expand Down
4 changes: 1 addition & 3 deletions flang/lib/Semantics/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,7 @@ const Symbol *FindInterface(const Symbol &symbol) {
return common::visit(
common::visitors{
[](const ProcEntityDetails &details) {
const Symbol *interface {
details.procInterface()
};
const Symbol *interface{details.procInterface()};
return interface ? FindInterface(*interface) : nullptr;
},
[](const ProcBindingDetails &details) {
Expand Down
29 changes: 29 additions & 0 deletions flang/test/Semantics/modfile64.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
! RUN: %python %S/test_modfile.py %s %flang_fc1
module mod0
interface proc
module procedure proc
end interface
contains
subroutine proc
end
end
module mod1
use mod0,renamed_proc=>proc
procedure(renamed_proc),pointer :: p
end module

!Expect: mod0.mod
!module mod0
!interface proc
!procedure::proc
!end interface
!contains
!subroutine proc()
!end
!end

!Expect: mod1.mod
!module mod1
!use mod0,only:renamed_proc=>proc
!procedure(renamed_proc),pointer::p
!end