Skip to content

Commit 3674a5f

Browse files
authored
[flang] Permit unused USE association of subprogram name (#134009)
A function or subroutine can allow an object of the same name to appear in its scope, so long as the name is not used. This is similar to the case of a name being imported from multiple distinct modules, and implemented by the same representation. It's not clear whether this is conforming behavior or a common extension.
1 parent c8bde44 commit 3674a5f

File tree

5 files changed

+42
-16
lines changed

5 files changed

+42
-16
lines changed

flang/include/flang/Support/Fortran-features.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
7575
VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg,
7676
MismatchingDummyProcedure, SubscriptedEmptyArray, UnsignedLiteralTruncation,
7777
CompatibleDeclarationsFromDistinctModules,
78-
NullActualForDefaultIntentAllocatable)
78+
NullActualForDefaultIntentAllocatable, UseAssociationIntoSameNameSubprogram)
7979

8080
using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
8181
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;

flang/lib/Semantics/resolve-names.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
719719
void NotePossibleBadForwardRef(const parser::Name &);
720720
std::optional<SourceName> HadForwardRef(const Symbol &) const;
721721
bool CheckPossibleBadForwardRef(const Symbol &);
722+
bool ConvertToUseError(Symbol &, const SourceName &, const Symbol &used);
722723

723724
bool inSpecificationPart_{false};
724725
bool deferImplicitTyping_{false};
@@ -3335,7 +3336,7 @@ ModuleVisitor::SymbolRename ModuleVisitor::AddUse(
33353336

33363337
// symbol must be either a Use or a Generic formed by merging two uses.
33373338
// Convert it to a UseError with this additional location.
3338-
static bool ConvertToUseError(
3339+
bool ScopeHandler::ConvertToUseError(
33393340
Symbol &symbol, const SourceName &location, const Symbol &used) {
33403341
if (auto *ued{symbol.detailsIf<UseErrorDetails>()}) {
33413342
ued->add_occurrence(location, used);
@@ -3353,9 +3354,25 @@ static bool ConvertToUseError(
33533354
symbol.set_details(
33543355
UseErrorDetails{*useDetails}.add_occurrence(location, used));
33553356
return true;
3356-
} else {
3357-
return false;
33583357
}
3358+
if (const auto *hostAssocDetails{symbol.detailsIf<HostAssocDetails>()};
3359+
hostAssocDetails && hostAssocDetails->symbol().has<SubprogramDetails>() &&
3360+
&symbol.owner() == &currScope() &&
3361+
&hostAssocDetails->symbol() == currScope().symbol()) {
3362+
// Handle USE-association of procedure FOO into function/subroutine FOO,
3363+
// replacing its place-holding HostAssocDetails symbol.
3364+
context().Warn(common::UsageWarning::UseAssociationIntoSameNameSubprogram,
3365+
location,
3366+
"'%s' is use-associated into a subprogram of the same name"_port_en_US,
3367+
used.name());
3368+
SourceName created{context().GetTempName(currScope())};
3369+
Symbol &tmpUse{MakeSymbol(created, Attrs(), UseDetails{location, used})};
3370+
UseErrorDetails useError{tmpUse.get<UseDetails>()};
3371+
useError.add_occurrence(location, hostAssocDetails->symbol());
3372+
symbol.set_details(std::move(useError));
3373+
return true;
3374+
}
3375+
return false;
33593376
}
33603377

33613378
// Two ultimate symbols are distinct, but they have the same name and come

flang/lib/Semantics/tools.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,16 +1733,20 @@ bool HadUseError(
17331733
at, "Reference to '%s' is ambiguous"_err_en_US, symbol->name())};
17341734
for (const auto &[location, sym] : details->occurrences()) {
17351735
const Symbol &ultimate{sym->GetUltimate()};
1736-
auto &attachment{
1737-
msg.Attach(location, "'%s' was use-associated from module '%s'"_en_US,
1738-
at, sym->owner().GetName().value())};
1739-
if (&*sym != &ultimate) {
1740-
// For incompatible definitions where one comes from a hermetic
1741-
// module file's incorporated dependences and the other from another
1742-
// module of the same name.
1743-
attachment.Attach(ultimate.name(),
1744-
"ultimately from '%s' in module '%s'"_en_US, ultimate.name(),
1745-
ultimate.owner().GetName().value());
1736+
if (sym->owner().IsModule()) {
1737+
auto &attachment{msg.Attach(location,
1738+
"'%s' was use-associated from module '%s'"_en_US, at,
1739+
sym->owner().GetName().value())};
1740+
if (&*sym != &ultimate) {
1741+
// For incompatible definitions where one comes from a hermetic
1742+
// module file's incorporated dependences and the other from another
1743+
// module of the same name.
1744+
attachment.Attach(ultimate.name(),
1745+
"ultimately from '%s' in module '%s'"_en_US, ultimate.name(),
1746+
ultimate.owner().GetName().value());
1747+
}
1748+
} else {
1749+
msg.Attach(sym->name(), "declared here"_en_US);
17461750
}
17471751
}
17481752
context.SetError(*symbol);

flang/lib/Support/Fortran-features.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ LanguageFeatureControl::LanguageFeatureControl() {
8585
warnUsage_.set(UsageWarning::UselessIomsg);
8686
warnUsage_.set(UsageWarning::UnsignedLiteralTruncation);
8787
warnUsage_.set(UsageWarning::NullActualForDefaultIntentAllocatable);
88+
warnUsage_.set(UsageWarning::UseAssociationIntoSameNameSubprogram);
8889
// New warnings, on by default
8990
warnLanguage_.set(LanguageFeature::SavedLocalInSpecExpr);
9091
warnLanguage_.set(LanguageFeature::NullActualForAllocatable);

flang/test/Semantics/resolve18.f90

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@ subroutine s(i)
2222
end module
2323

2424
subroutine foo
25-
!ERROR: Cannot use-associate 'foo'; it is already declared in this scope
25+
!PORTABILITY: 'foo' is use-associated into a subprogram of the same name
2626
use m1
27+
!ERROR: Reference to 'foo' is ambiguous
28+
call foo
2729
end
2830

2931
subroutine bar
30-
!ERROR: Cannot use-associate 'bar'; it is already declared in this scope
32+
!PORTABILITY: 'foo' is use-associated into a subprogram of the same name
3133
use m1, bar => foo
34+
!ERROR: Reference to 'bar' is ambiguous
35+
call bar
3236
end
3337

3438
!OK to use-associate a type with the same name as a generic

0 commit comments

Comments
 (0)