Skip to content

Commit a26cd2d

Browse files
authored
[Flang] Fix symbol name clash when dummy procedure name is the same as common-block-name (#155508)
Dummy procedures in interface blocks are not external procedures that need to be linked. Do not externalize those. Fixes #122822
1 parent 5777f71 commit a26cd2d

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,49 @@ void ExternalNameConversionPass::runOnOperation() {
7676
auto *context = &getContext();
7777

7878
llvm::DenseMap<mlir::StringAttr, mlir::FlatSymbolRefAttr> remappings;
79+
mlir::SymbolTable symbolTable(op);
7980

8081
auto processFctOrGlobal = [&](mlir::Operation &funcOrGlobal) {
8182
auto symName = funcOrGlobal.getAttrOfType<mlir::StringAttr>(
8283
mlir::SymbolTable::getSymbolAttrName());
8384
auto deconstructedName = fir::NameUniquer::deconstruct(symName);
8485
if (fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) {
86+
// Check if this is a private function that would conflict with a common
87+
// block and get its mangled name.
88+
if (auto funcOp = llvm::dyn_cast<mlir::func::FuncOp>(funcOrGlobal)) {
89+
if (funcOp.isPrivate()) {
90+
std::string mangledName =
91+
mangleExternalName(deconstructedName, appendUnderscoreOpt);
92+
auto mod = funcOp->getParentOfType<mlir::ModuleOp>();
93+
bool hasConflictingCommonBlock = false;
94+
95+
// Check if any existing global has the same mangled name.
96+
if (symbolTable.lookup<fir::GlobalOp>(mangledName))
97+
hasConflictingCommonBlock = true;
98+
99+
// Skip externalization if the function has a conflicting common block
100+
// and is not directly called (i.e. procedure pointers or type
101+
// specifications)
102+
if (hasConflictingCommonBlock) {
103+
bool isDirectlyCalled = false;
104+
std::optional<SymbolTable::UseRange> uses =
105+
funcOp.getSymbolUses(mod);
106+
if (uses.has_value()) {
107+
for (auto use : *uses) {
108+
mlir::Operation *user = use.getUser();
109+
if (mlir::isa<fir::CallOp>(user) ||
110+
mlir::isa<mlir::func::CallOp>(user)) {
111+
isDirectlyCalled = true;
112+
break;
113+
}
114+
}
115+
}
116+
if (!isDirectlyCalled)
117+
return;
118+
}
119+
}
120+
}
121+
85122
auto newName = mangleExternalName(deconstructedName, appendUnderscoreOpt);
86123
auto newAttr = mlir::StringAttr::get(context, newName);
87124
mlir::SymbolTable::setSymbolName(&funcOrGlobal, newAttr);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
! RUN: bbc -emit-fir %s -o - | FileCheck %s
2+
3+
subroutine ss5()
4+
common /com_dummy1/ x
5+
! CHECK: fir.global common @com_dummy1_
6+
interface
7+
subroutine com_dummy1()
8+
end subroutine
9+
end interface
10+
! CHECK: func.func private @_QPcom_dummy1()
11+
print *,fun_sub(com_dummy1)
12+
end

0 commit comments

Comments
 (0)