Skip to content

Commit 1fb926d

Browse files
[flang] Mangle main program's symbol name to make it distinct from the other symbols
The following code is now accepted: ``` module m end program m use m end ``` The PROGRAM name doesn't really have an effect on the compilation result, so it shouldn't result in symbol name conflicts.
1 parent 08a8e1c commit 1fb926d

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

flang/include/flang/Semantics/symbol.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,14 @@ class ModuleDetails : public WithOmpDeclarative {
107107

108108
class MainProgramDetails : public WithOmpDeclarative {
109109
public:
110+
MainProgramDetails() {}
111+
MainProgramDetails(const SourceName &name, const SourceName &scopeName)
112+
: name_{name}, scopeName_{scopeName} {}
113+
const SourceName& scopeName() const { return scopeName_; }
114+
const SourceName& name() const { return name_; }
110115
private:
116+
SourceName name_; // Original main program symbol name
117+
SourceName scopeName_; // Main program symbol name used in scope symbol table
111118
};
112119

113120
class WithBindName {
@@ -828,7 +835,15 @@ class Symbol {
828835
using Flags = common::EnumSet<Flag, Flag_enumSize>;
829836

830837
const Scope &owner() const { return *owner_; }
831-
const SourceName &name() const { return name_; }
838+
839+
const SourceName &name() const {
840+
if (const auto* details = detailsIf<MainProgramDetails>()) {
841+
// For main program symbol always return the original name
842+
return details->name();
843+
}
844+
return name_;
845+
}
846+
832847
Attrs &attrs() { return attrs_; }
833848
const Attrs &attrs() const { return attrs_; }
834849
Attrs &implicitAttrs() { return implicitAttrs_; }

flang/lib/Semantics/resolve-names.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,18 @@ class ScopeHandler : public ImplicitRulesVisitor {
599599
// Note: don't use FindSymbol here. If this is a derived type scope,
600600
// we want to detect whether the name is already declared as a component.
601601
auto *symbol{FindInScope(name)};
602+
if constexpr (std::is_same_v<MainProgramDetails, D>) {
603+
CHECK(!symbol || !symbol->has<MainProgramDetails>());
604+
// Use mangled main program name from MainProgramDetails, in order
605+
// to avoid conflicts with the other kinds of symbols having the same
606+
// name.
607+
symbol = FindInScope(details.scopeName());
608+
if (!symbol) {
609+
auto &result{MakeSymbol(details.scopeName(), attrs)};
610+
result.set_details(std::move(details));
611+
return result;
612+
}
613+
}
602614
if (!symbol) {
603615
symbol = &MakeSymbol(name, attrs);
604616
symbol->set_details(std::move(details));
@@ -10273,10 +10285,13 @@ void ResolveNamesVisitor::AddSubpNames(ProgramTree &node) {
1027310285
bool ResolveNamesVisitor::BeginScopeForNode(const ProgramTree &node) {
1027410286
switch (node.GetKind()) {
1027510287
SWITCH_COVERS_ALL_CASES
10276-
case ProgramTree::Kind::Program:
10288+
case ProgramTree::Kind::Program: {
10289+
SourceName name = node.name().source;
10290+
SourceName scopeName = context().SaveTempName(name.ToString() + "$main"s);
1027710291
PushScope(Scope::Kind::MainProgram,
10278-
&MakeSymbol(node.name(), MainProgramDetails{}));
10292+
&MakeSymbol(node.name(), MainProgramDetails{name, scopeName}));
1027910293
return true;
10294+
}
1028010295
case ProgramTree::Kind::Function:
1028110296
case ProgramTree::Kind::Subroutine:
1028210297
return BeginSubprogram(node.name(), node.GetSubpFlag(),

0 commit comments

Comments
 (0)