Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,12 +646,18 @@ class ScopeHandler : public ImplicitRulesVisitor {
}
if (symbol->CanReplaceDetails(details)) {
// update the existing symbol
CheckDuplicatedAttrs(name, *symbol, attrs);
SetExplicitAttrs(*symbol, attrs);
if constexpr (std::is_same_v<SubprogramDetails, D>) {
// Dummy argument defined by explicit interface?
details.set_isDummy(IsDummy(*symbol));
if (symbol->has<ProcEntityDetails>()) {
// Bare "EXTERNAL" dummy replaced with explicit INTERFACE
context().Warn(common::LanguageFeature::RedundantAttribute, name,
"Dummy argument '%s' was declared earlier as EXTERNAL"_warn_en_US,
name);
}
}
CheckDuplicatedAttrs(name, *symbol, attrs);
SetExplicitAttrs(*symbol, attrs);
symbol->set_details(std::move(details));
return *symbol;
} else if constexpr (std::is_same_v<UnknownDetails, D>) {
Expand Down
16 changes: 10 additions & 6 deletions flang/lib/Semantics/symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,23 +330,27 @@ bool Symbol::CanReplaceDetails(const Details &details) const {
common::visitors{
[](const UseErrorDetails &) { return true; },
[&](const ObjectEntityDetails &) { return has<EntityDetails>(); },
[&](const ProcEntityDetails &) { return has<EntityDetails>(); },
[&](const ProcEntityDetails &x) { return has<EntityDetails>(); },
[&](const SubprogramDetails &) {
if (const auto *oldProc{detailsIf<ProcEntityDetails>()}) {
// Can replace bare "EXTERNAL dummy" with explicit INTERFACE
return oldProc->isDummy() && !oldProc->procInterface() &&
attrs().test(Attr::EXTERNAL) && !test(Flag::Function) &&
!test(Flag::Subroutine);
}
return has<SubprogramNameDetails>() || has<EntityDetails>();
},
[&](const DerivedTypeDetails &) {
const auto *derived{this->detailsIf<DerivedTypeDetails>()};
return derived && derived->isForwardReferenced();
},
[&](const UseDetails &x) {
const auto *use{this->detailsIf<UseDetails>()};
const auto *use{detailsIf<UseDetails>()};
return use && use->symbol() == x.symbol();
},
[&](const HostAssocDetails &) {
return this->has<HostAssocDetails>();
},
[&](const HostAssocDetails &) { return has<HostAssocDetails>(); },
[&](const UserReductionDetails &) {
return this->has<UserReductionDetails>();
return has<UserReductionDetails>();
},
[](const auto &) { return false; },
},
Expand Down
8 changes: 8 additions & 0 deletions flang/test/Semantics/resolve20.f90
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,12 @@ subroutine test
!ERROR: Abstract procedure interface 'f' may not be referenced
x = f()
end subroutine
subroutine baz(foo)
external foo
interface
!WARNING: Dummy argument 'foo' was declared earlier as EXTERNAL [-Wredundant-attribute]
subroutine foo(x)
end
end interface
end
end module
Loading