@@ -746,6 +746,9 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
746
746
std::optional<SourceName> source;
747
747
} funcInfo_;
748
748
749
+ // Edits an existing symbol created for earlier calls to a subprogram or ENTRY
750
+ // so that it can be replaced by a later definition.
751
+ bool HandlePreviousCalls (const parser::Name &, Symbol &, Symbol::Flag);
749
752
// Create a subprogram symbol in the current scope and push a new scope.
750
753
void CheckExtantProc (const parser::Name &, Symbol::Flag);
751
754
Symbol &PushSubprogramScope (const parser::Name &, Symbol::Flag);
@@ -3079,8 +3082,11 @@ void SubprogramVisitor::Post(const parser::EntryStmt &stmt) {
3079
3082
dummy->name (), " Previous declaration of '%s'" _en_US);
3080
3083
}},
3081
3084
dummy->details ());
3085
+ } else if (inExecutionPart_) {
3086
+ dummy = &MakeSymbol (*dummyName, ObjectEntityDetails{true });
3087
+ ApplyImplicitRules (*dummy);
3082
3088
} else {
3083
- dummy = &MakeSymbol (*dummyName, EntityDetails ( true ) );
3089
+ dummy = &MakeSymbol (*dummyName, EntityDetails{ true } );
3084
3090
}
3085
3091
entryDetails.add_dummyArg (*dummy);
3086
3092
} else {
@@ -3096,20 +3102,11 @@ void SubprogramVisitor::Post(const parser::EntryStmt &stmt) {
3096
3102
Symbol::Flag subpFlag{
3097
3103
inFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine};
3098
3104
Scope &outer{inclusiveScope.parent ()}; // global or module scope
3105
+ if (outer.IsModule () && !attrs.test (Attr::PRIVATE)) {
3106
+ attrs.set (Attr::PUBLIC);
3107
+ }
3099
3108
if (Symbol * extant{FindSymbol (outer, name)}) {
3100
- if (extant->has <ProcEntityDetails>()) {
3101
- if (!extant->test (subpFlag)) {
3102
- Say2 (name,
3103
- subpFlag == Symbol::Flag::Function
3104
- ? " '%s' was previously called as a subroutine" _err_en_US
3105
- : " '%s' was previously called as a function" _err_en_US,
3106
- *extant, " Previous call of '%s'" _en_US);
3107
- }
3108
- if (extant->attrs ().test (Attr::PRIVATE)) {
3109
- attrs.set (Attr::PRIVATE);
3110
- }
3111
- outer.erase (extant->name ());
3112
- } else {
3109
+ if (!HandlePreviousCalls (name, *extant, subpFlag)) {
3113
3110
if (outer.IsGlobal ()) {
3114
3111
Say2 (name, " '%s' is already defined as a global identifier" _err_en_US,
3115
3112
*extant, " Previous definition of '%s'" _en_US);
@@ -3119,14 +3116,8 @@ void SubprogramVisitor::Post(const parser::EntryStmt &stmt) {
3119
3116
return ;
3120
3117
}
3121
3118
}
3122
- if (outer.IsModule () && !attrs.test (Attr::PRIVATE)) {
3123
- attrs.set (Attr::PUBLIC);
3124
- }
3125
3119
Symbol &entrySymbol{MakeSymbol (outer, name.source , attrs)};
3126
3120
entrySymbol.set_details (std::move (entryDetails));
3127
- if (outer.IsGlobal ()) {
3128
- MakeExternal (entrySymbol);
3129
- }
3130
3121
SetBindNameOn (entrySymbol);
3131
3122
entrySymbol.set (subpFlag);
3132
3123
Resolve (name, entrySymbol);
@@ -3186,24 +3177,37 @@ bool SubprogramVisitor::BeginSubprogram(
3186
3177
3187
3178
void SubprogramVisitor::EndSubprogram () { PopScope (); }
3188
3179
3180
+ bool SubprogramVisitor::HandlePreviousCalls (
3181
+ const parser::Name &name, Symbol &symbol, Symbol::Flag subpFlag) {
3182
+ if (const auto *proc{symbol.detailsIf <ProcEntityDetails>()}; proc &&
3183
+ !proc->isDummy () &&
3184
+ !symbol.attrs ().HasAny (Attrs{Attr::INTRINSIC, Attr::POINTER})) {
3185
+ // There's a symbol created for previous calls to this subprogram or
3186
+ // ENTRY's name. We have to replace that symbol in situ to avoid the
3187
+ // obligation to rewrite symbol pointers in the parse tree.
3188
+ if (!symbol.test (subpFlag)) {
3189
+ Say2 (name,
3190
+ subpFlag == Symbol::Flag::Function
3191
+ ? " '%s' was previously called as a subroutine" _err_en_US
3192
+ : " '%s' was previously called as a function" _err_en_US,
3193
+ symbol, " Previous call of '%s'" _en_US);
3194
+ }
3195
+ EntityDetails entity;
3196
+ if (proc->type ()) {
3197
+ entity.set_type (*proc->type ());
3198
+ }
3199
+ symbol.details () = std::move (entity);
3200
+ return true ;
3201
+ } else {
3202
+ return symbol.has <UnknownDetails>() || symbol.has <SubprogramNameDetails>();
3203
+ }
3204
+ }
3205
+
3189
3206
void SubprogramVisitor::CheckExtantProc (
3190
3207
const parser::Name &name, Symbol::Flag subpFlag) {
3191
3208
if (auto *prev{FindSymbol (name)}) {
3192
- if (prev->attrs ().test (Attr::EXTERNAL) && prev->has <ProcEntityDetails>()) {
3193
- // this subprogram was previously called, now being declared
3194
- if (!prev->test (subpFlag)) {
3195
- Say2 (name,
3196
- subpFlag == Symbol::Flag::Function
3197
- ? " '%s' was previously called as a subroutine" _err_en_US
3198
- : " '%s' was previously called as a function" _err_en_US,
3199
- *prev, " Previous call of '%s'" _en_US);
3200
- }
3201
- EraseSymbol (name);
3202
- } else if (const auto *details{prev->detailsIf <EntityDetails>()}) {
3203
- if (!details->isDummy ()) {
3204
- Say2 (name, " Procedure '%s' was previously declared" _err_en_US, *prev,
3205
- " Previous declaration of '%s'" _en_US);
3206
- }
3209
+ if (!IsDummy (*prev) && !HandlePreviousCalls (name, *prev, subpFlag)) {
3210
+ SayAlreadyDeclared (name, *prev);
3207
3211
}
3208
3212
}
3209
3213
}
0 commit comments