@@ -687,7 +687,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
687
687
Symbol &, bool respectImplicitNoneType = true);
688
688
void CheckEntryDummyUse(SourceName, Symbol *);
689
689
bool ConvertToObjectEntity(Symbol &);
690
- bool ConvertToProcEntity(Symbol &);
690
+ bool ConvertToProcEntity(Symbol &, std::optional<SourceName> = std::nullopt );
691
691
692
692
const DeclTypeSpec &MakeNumericType(
693
693
TypeCategory, const std::optional<parser::KindSelector> &);
@@ -2253,14 +2253,19 @@ void ScopeHandler::SayWithReason(const parser::Name &name, Symbol &symbol,
2253
2253
2254
2254
void ScopeHandler::SayWithDecl(
2255
2255
const parser::Name &name, Symbol &symbol, MessageFixedText &&msg) {
2256
- bool isFatal{msg.IsFatal()};
2257
- Say(name, std::move(msg), symbol.name())
2258
- .Attach(Message{symbol.name(),
2259
- symbol.test(Symbol::Flag::Implicit)
2260
- ? "Implicit declaration of '%s'"_en_US
2261
- : "Declaration of '%s'"_en_US,
2262
- name.source});
2263
- context().SetError(symbol, isFatal);
2256
+ auto &message{Say(name, std::move(msg), symbol.name())
2257
+ .Attach(Message{symbol.name(),
2258
+ symbol.test(Symbol::Flag::Implicit)
2259
+ ? "Implicit declaration of '%s'"_en_US
2260
+ : "Declaration of '%s'"_en_US,
2261
+ name.source})};
2262
+ if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}) {
2263
+ if (auto usedAsProc{proc->usedAsProcedureHere()}) {
2264
+ if (usedAsProc->begin() != symbol.name().begin()) {
2265
+ message.Attach(Message{*usedAsProc, "Referenced as a procedure"_en_US});
2266
+ }
2267
+ }
2268
+ }
2264
2269
}
2265
2270
2266
2271
void ScopeHandler::SayLocalMustBeVariable(
@@ -2659,9 +2664,9 @@ bool ScopeHandler::ConvertToObjectEntity(Symbol &symbol) {
2659
2664
return true;
2660
2665
}
2661
2666
// Convert symbol to be a ProcEntity or return false if it can't be.
2662
- bool ScopeHandler::ConvertToProcEntity(Symbol &symbol) {
2667
+ bool ScopeHandler::ConvertToProcEntity(
2668
+ Symbol &symbol, std::optional<SourceName> usedHere) {
2663
2669
if (symbol.has<ProcEntityDetails>()) {
2664
- // nothing to do
2665
2670
} else if (symbol.has<UnknownDetails>()) {
2666
2671
symbol.set_details(ProcEntityDetails{});
2667
2672
} else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
@@ -2684,6 +2689,10 @@ bool ScopeHandler::ConvertToProcEntity(Symbol &symbol) {
2684
2689
} else {
2685
2690
return false;
2686
2691
}
2692
+ auto &proc{symbol.get<ProcEntityDetails>()};
2693
+ if (usedHere && !proc.usedAsProcedureHere()) {
2694
+ proc.set_usedAsProcedureHere(*usedHere);
2695
+ }
2687
2696
return true;
2688
2697
}
2689
2698
@@ -4805,7 +4814,7 @@ bool DeclarationVisitor::Pre(const parser::ExternalStmt &x) {
4805
4814
HandleAttributeStmt(Attr::EXTERNAL, x.v);
4806
4815
for (const auto &name : x.v) {
4807
4816
auto *symbol{FindSymbol(name)};
4808
- if (!ConvertToProcEntity(DEREF(symbol))) {
4817
+ if (!ConvertToProcEntity(DEREF(symbol), name.source )) {
4809
4818
// Check if previous symbol is an interface.
4810
4819
if (auto *details{symbol->detailsIf<SubprogramDetails>()}) {
4811
4820
if (details->isInterface()) {
@@ -4845,7 +4854,7 @@ void DeclarationVisitor::DeclareIntrinsic(const parser::Name &name) {
4845
4854
auto &symbol{DEREF(FindSymbol(name))};
4846
4855
if (symbol.has<GenericDetails>()) {
4847
4856
// Generic interface is extending intrinsic; ok
4848
- } else if (!ConvertToProcEntity(symbol)) {
4857
+ } else if (!ConvertToProcEntity(symbol, name.source )) {
4849
4858
SayWithDecl(
4850
4859
name, symbol, "INTRINSIC attribute not allowed on '%s'"_err_en_US);
4851
4860
} else if (symbol.attrs().test(Attr::EXTERNAL)) { // C840
@@ -7705,6 +7714,7 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
7705
7714
} else if (!context().HasError(*name->symbol)) {
7706
7715
SayWithDecl(*name, *name->symbol,
7707
7716
"Cannot reference function '%s' as data"_err_en_US);
7717
+ context().SetError(*name->symbol);
7708
7718
}
7709
7719
}
7710
7720
return name;
@@ -8119,7 +8129,7 @@ void ResolveNamesVisitor::HandleProcedureName(
8119
8129
symbol = &MakeSymbol(context().globalScope(), name.source, Attrs{});
8120
8130
}
8121
8131
Resolve(name, *symbol);
8122
- ConvertToProcEntity(*symbol);
8132
+ ConvertToProcEntity(*symbol, name.source );
8123
8133
if (!symbol->attrs().test(Attr::INTRINSIC)) {
8124
8134
if (CheckImplicitNoneExternal(name.source, *symbol)) {
8125
8135
MakeExternal(*symbol);
@@ -8144,7 +8154,7 @@ void ResolveNamesVisitor::HandleProcedureName(
8144
8154
name.symbol = symbol;
8145
8155
}
8146
8156
CheckEntryDummyUse(name.source, symbol);
8147
- bool convertedToProcEntity{ConvertToProcEntity(*symbol)};
8157
+ bool convertedToProcEntity{ConvertToProcEntity(*symbol, name.source )};
8148
8158
if (convertedToProcEntity && !symbol->attrs().test(Attr::EXTERNAL) &&
8149
8159
IsIntrinsic(symbol->name(), flag) && !IsDummy(*symbol)) {
8150
8160
AcquireIntrinsicProcedureFlags(*symbol);
@@ -8203,7 +8213,7 @@ void ResolveNamesVisitor::NoteExecutablePartCall(
8203
8213
? Symbol::Flag::Function
8204
8214
: Symbol::Flag::Subroutine};
8205
8215
if (!symbol->test(other)) {
8206
- ConvertToProcEntity(*symbol);
8216
+ ConvertToProcEntity(*symbol, name );
8207
8217
if (auto *details{symbol->detailsIf<ProcEntityDetails>()}) {
8208
8218
symbol->set(flag);
8209
8219
if (IsDummy(*symbol)) {
@@ -8240,11 +8250,13 @@ bool ResolveNamesVisitor::SetProcFlag(
8240
8250
if (symbol.test(Symbol::Flag::Function) && flag == Symbol::Flag::Subroutine) {
8241
8251
SayWithDecl(
8242
8252
name, symbol, "Cannot call function '%s' like a subroutine"_err_en_US);
8253
+ context().SetError(symbol);
8243
8254
return false;
8244
8255
} else if (symbol.test(Symbol::Flag::Subroutine) &&
8245
8256
flag == Symbol::Flag::Function) {
8246
8257
SayWithDecl(
8247
8258
name, symbol, "Cannot call subroutine '%s' like a function"_err_en_US);
8259
+ context().SetError(symbol);
8248
8260
return false;
8249
8261
} else if (flag == Symbol::Flag::Function &&
8250
8262
IsLocallyImplicitGlobalSymbol(symbol, name) &&
@@ -8263,6 +8275,7 @@ bool ResolveNamesVisitor::SetProcFlag(
8263
8275
} else if (symbol.GetType() && flag == Symbol::Flag::Subroutine) {
8264
8276
SayWithDecl(
8265
8277
name, symbol, "Cannot call function '%s' like a subroutine"_err_en_US);
8278
+ context().SetError(symbol);
8266
8279
} else if (symbol.attrs().test(Attr::INTRINSIC)) {
8267
8280
AcquireIntrinsicProcedureFlags(symbol);
8268
8281
}
@@ -8724,7 +8737,7 @@ bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt &x) {
8724
8737
context().globalScope(), name->source, Attrs{Attr::EXTERNAL})};
8725
8738
symbol.implicitAttrs().set(Attr::EXTERNAL);
8726
8739
Resolve(*name, symbol);
8727
- ConvertToProcEntity(symbol);
8740
+ ConvertToProcEntity(symbol, name->source );
8728
8741
return false;
8729
8742
}
8730
8743
}
0 commit comments