[flang-commits] [flang] 83ca78d - [flang] Emit "raw" name for procedure interface in module file (#83915)
via flang-commits
flang-commits at lists.llvm.org
Tue Mar 5 12:00:50 PST 2024
Author: Peter Klausler
Date: 2024-03-05T12:00:46-08:00
New Revision: 83ca78deb9075e764f89fad83af926357eb78967
URL: https://github.com/llvm/llvm-project/commit/83ca78deb9075e764f89fad83af926357eb78967
DIFF: https://github.com/llvm/llvm-project/commit/83ca78deb9075e764f89fad83af926357eb78967.diff
LOG: [flang] Emit "raw" name for procedure interface in module file (#83915)
Save both the raw procedure interface symbol as well as the result of
passing it through GetUltimate() and BypassGeneric() in symbol table
entries with ProcEntityDetails. The raw symbol of the interface needs to
be the one used for emitting procedure symbols to module files.
Fixes https://github.com/llvm/llvm-project/issues/83836.
Added:
flang/test/Semantics/modfile64.f90
Modified:
flang/include/flang/Semantics/symbol.h
flang/lib/Semantics/check-declarations.cpp
flang/lib/Semantics/mod-file.cpp
flang/lib/Semantics/resolve-names-utils.cpp
flang/lib/Semantics/resolve-names.cpp
flang/lib/Semantics/symbol.cpp
flang/lib/Semantics/tools.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 125025dab5f448..c3175a5d1a111d 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -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,
@@ -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};
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index 729321d3bf1701..431cef20793508 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -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) ||
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 37fe0240537b8e..b4df7216a33e20 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -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());
}
@@ -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());
}
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index b901080e2860c4..801473876e7e2b 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -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);
}
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 26cae833edfcff..67392a02cf1862 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -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)) {
@@ -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()}) {
@@ -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());
}
}
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 2ab3189cf4064e..381905b89fb2dd 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -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());
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index f931ae07072010..bf999b090419c6 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -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) {
diff --git a/flang/test/Semantics/modfile64.f90 b/flang/test/Semantics/modfile64.f90
new file mode 100644
index 00000000000000..e9df005c9ffd31
--- /dev/null
+++ b/flang/test/Semantics/modfile64.f90
@@ -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
More information about the flang-commits
mailing list