Skip to content

Commit 83ca78d

Browse files
authored
[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 #83836.
1 parent b3b408b commit 83ca78d

File tree

8 files changed

+55
-21
lines changed

8 files changed

+55
-21
lines changed

flang/include/flang/Semantics/symbol.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,12 @@ class ProcEntityDetails : public EntityDetails, public WithPassArg {
417417
ProcEntityDetails(ProcEntityDetails &&) = default;
418418
ProcEntityDetails &operator=(const ProcEntityDetails &) = default;
419419

420+
const Symbol *rawProcInterface() const { return rawProcInterface_; }
420421
const Symbol *procInterface() const { return procInterface_; }
421-
void set_procInterface(const Symbol &sym) { procInterface_ = &sym; }
422+
void set_procInterfaces(const Symbol &raw, const Symbol &resolved) {
423+
rawProcInterface_ = &raw;
424+
procInterface_ = &resolved;
425+
}
422426
inline bool HasExplicitInterface() const;
423427

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

432436
private:
437+
const Symbol *rawProcInterface_{nullptr};
433438
const Symbol *procInterface_{nullptr};
434439
std::optional<const Symbol *> init_;
435440
bool isCUDAKernel_{false};

flang/lib/Semantics/check-declarations.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,9 +1195,7 @@ void CheckHelper::CheckArraySpec(
11951195
void CheckHelper::CheckProcEntity(
11961196
const Symbol &symbol, const ProcEntityDetails &details) {
11971197
CheckSymbolType(symbol);
1198-
const Symbol *interface {
1199-
details.procInterface() ? &details.procInterface()->GetUltimate() : nullptr
1200-
};
1198+
const Symbol *interface{details.procInterface()};
12011199
if (details.isDummy()) {
12021200
if (!symbol.attrs().test(Attr::POINTER) && // C843
12031201
(symbol.attrs().test(Attr::INTENT_IN) ||

flang/lib/Semantics/mod-file.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -924,8 +924,8 @@ void ModFileWriter::PutProcEntity(llvm::raw_ostream &os, const Symbol &symbol) {
924924
os, symbol,
925925
[&]() {
926926
os << "procedure(";
927-
if (details.procInterface()) {
928-
os << details.procInterface()->name();
927+
if (details.rawProcInterface()) {
928+
os << details.rawProcInterface()->name();
929929
} else if (details.type()) {
930930
PutType(os, *details.type());
931931
}
@@ -1622,8 +1622,8 @@ void SubprogramSymbolCollector::DoSymbol(
16221622
}
16231623
},
16241624
[this](const ProcEntityDetails &details) {
1625-
if (details.procInterface()) {
1626-
DoSymbol(*details.procInterface());
1625+
if (details.rawProcInterface()) {
1626+
DoSymbol(*details.rawProcInterface());
16271627
} else {
16281628
DoType(details.type());
16291629
}

flang/lib/Semantics/resolve-names-utils.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -845,8 +845,9 @@ void SymbolMapper::MapSymbolExprs(Symbol &symbol) {
845845
},
846846
[&](ProcEntityDetails &proc) {
847847
if (const Symbol *
848-
mappedSymbol{MapInterface(proc.procInterface())}) {
849-
proc.set_procInterface(*mappedSymbol);
848+
mappedSymbol{MapInterface(proc.rawProcInterface())}) {
849+
proc.set_procInterfaces(
850+
*mappedSymbol, BypassGeneric(mappedSymbol->GetUltimate()));
850851
} else if (const DeclTypeSpec * mappedType{MapType(proc.type())}) {
851852
proc.set_type(*mappedType);
852853
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4983,7 +4983,8 @@ Symbol &DeclarationVisitor::DeclareProcEntity(
49834983
"The interface for procedure '%s' has already been declared"_err_en_US);
49844984
context().SetError(symbol);
49854985
} else if (interface) {
4986-
details->set_procInterface(*interface);
4986+
details->set_procInterfaces(
4987+
*interface, BypassGeneric(interface->GetUltimate()));
49874988
if (interface->test(Symbol::Flag::Function)) {
49884989
symbol.set(Symbol::Flag::Function);
49894990
} else if (interface->test(Symbol::Flag::Subroutine)) {
@@ -5658,10 +5659,10 @@ void DeclarationVisitor::Post(const parser::ProcInterface &x) {
56585659
}
56595660
void DeclarationVisitor::Post(const parser::ProcDecl &x) {
56605661
const auto &name{std::get<parser::Name>(x.t)};
5661-
const Symbol *procInterface{nullptr};
5662-
if (interfaceName_ && interfaceName_->symbol) {
5663-
procInterface = &BypassGeneric(*interfaceName_->symbol);
5664-
}
5662+
// Don't use BypassGeneric or GetUltimate on this symbol, they can
5663+
// lead to unusable names in module files.
5664+
const Symbol *procInterface{
5665+
interfaceName_ ? interfaceName_->symbol : nullptr};
56655666
auto attrs{HandleSaveName(name.source, GetAttrs())};
56665667
DerivedTypeDetails *dtDetails{nullptr};
56675668
if (Symbol * symbol{currScope().symbol()}) {
@@ -6624,10 +6625,9 @@ void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
66246625
if (const Symbol * symbol{name.symbol}) {
66256626
const Symbol &ultimate{symbol->GetUltimate()};
66266627
if (!context().HasError(*symbol) && !context().HasError(ultimate) &&
6627-
!ultimate.HasExplicitInterface()) {
6628+
!BypassGeneric(ultimate).HasExplicitInterface()) {
66286629
Say(name,
6629-
"'%s' must be an abstract interface or a procedure with "
6630-
"an explicit interface"_err_en_US,
6630+
"'%s' must be an abstract interface or a procedure with an explicit interface"_err_en_US,
66316631
symbol->name());
66326632
}
66336633
}

flang/lib/Semantics/symbol.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,9 @@ llvm::raw_ostream &operator<<(
452452
llvm::raw_ostream &operator<<(
453453
llvm::raw_ostream &os, const ProcEntityDetails &x) {
454454
if (x.procInterface_) {
455+
if (x.rawProcInterface_ != x.procInterface_) {
456+
os << ' ' << x.rawProcInterface_->name() << " ->";
457+
}
455458
os << ' ' << x.procInterface_->name();
456459
} else {
457460
DumpType(os, x.type());

flang/lib/Semantics/tools.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,7 @@ const Symbol *FindInterface(const Symbol &symbol) {
465465
return common::visit(
466466
common::visitors{
467467
[](const ProcEntityDetails &details) {
468-
const Symbol *interface {
469-
details.procInterface()
470-
};
468+
const Symbol *interface{details.procInterface()};
471469
return interface ? FindInterface(*interface) : nullptr;
472470
},
473471
[](const ProcBindingDetails &details) {

flang/test/Semantics/modfile64.f90

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
! RUN: %python %S/test_modfile.py %s %flang_fc1
2+
module mod0
3+
interface proc
4+
module procedure proc
5+
end interface
6+
contains
7+
subroutine proc
8+
end
9+
end
10+
module mod1
11+
use mod0,renamed_proc=>proc
12+
procedure(renamed_proc),pointer :: p
13+
end module
14+
15+
!Expect: mod0.mod
16+
!module mod0
17+
!interface proc
18+
!procedure::proc
19+
!end interface
20+
!contains
21+
!subroutine proc()
22+
!end
23+
!end
24+
25+
!Expect: mod1.mod
26+
!module mod1
27+
!use mod0,only:renamed_proc=>proc
28+
!procedure(renamed_proc),pointer::p
29+
!end

0 commit comments

Comments
 (0)