@@ -488,6 +488,10 @@ class FuncResultStack {
488488 // Result symbol
489489 Symbol *resultSymbol{nullptr };
490490 bool inFunctionStmt{false }; // true between Pre/Post of FunctionStmt
491+ // Functions with previous implicitly-typed references get those types
492+ // checked against their later definitions.
493+ const DeclTypeSpec *previousImplicitType{nullptr };
494+ SourceName previousName;
491495 };
492496
493497 // Completes the definition of the top function's result.
@@ -943,7 +947,7 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
943947 // Edits an existing symbol created for earlier calls to a subprogram or ENTRY
944948 // so that it can be replaced by a later definition.
945949 bool HandlePreviousCalls (const parser::Name &, Symbol &, Symbol::Flag);
946- void CheckExtantProc (const parser::Name &, Symbol::Flag);
950+ const Symbol * CheckExtantProc (const parser::Name &, Symbol::Flag);
947951 // Create a subprogram symbol in the current scope and push a new scope.
948952 Symbol &PushSubprogramScope (const parser::Name &, Symbol::Flag,
949953 const parser::LanguageBindingSpec * = nullptr ,
@@ -2691,11 +2695,17 @@ void ArraySpecVisitor::PostAttrSpec() {
26912695
26922696FuncResultStack::~FuncResultStack () { CHECK (stack_.empty ()); }
26932697
2698+ static bool TypesMismatchIfNonNull (
2699+ const DeclTypeSpec *type1, const DeclTypeSpec *type2) {
2700+ return type1 && type2 && *type1 != *type2;
2701+ }
2702+
26942703void FuncResultStack::CompleteFunctionResultType () {
26952704 // If the function has a type in the prefix, process it now.
26962705 FuncInfo *info{Top ()};
2697- if (info && &info->scope == &scopeHandler_.currScope ()) {
2698- if (info->parsedType && info->resultSymbol ) {
2706+ if (info && &info->scope == &scopeHandler_.currScope () &&
2707+ info->resultSymbol ) {
2708+ if (info->parsedType ) {
26992709 scopeHandler_.messageHandler ().set_currStmtSource (info->source );
27002710 if (const auto *type{
27012711 scopeHandler_.ProcessTypeSpec (*info->parsedType , true )}) {
@@ -2712,6 +2722,16 @@ void FuncResultStack::CompleteFunctionResultType() {
27122722 }
27132723 info->parsedType = nullptr ;
27142724 }
2725+ if (TypesMismatchIfNonNull (
2726+ info->resultSymbol ->GetType (), info->previousImplicitType )) {
2727+ scopeHandler_
2728+ .Say (info->resultSymbol ->name (),
2729+ " Function '%s' has a result type that differs from the implicit type it obtained in a previous reference" _err_en_US,
2730+ info->previousName )
2731+ .Attach (info->previousName ,
2732+ " Previous reference implicitly typed as %s\n " _en_US,
2733+ info->previousImplicitType ->AsFortran ());
2734+ }
27152735 }
27162736}
27172737
@@ -4761,9 +4781,7 @@ void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) {
47614781 if (info.resultName && !distinctResultName) {
47624782 context ().Warn (common::UsageWarning::HomonymousResult,
47634783 info.resultName ->source ,
4764- " The function name should not appear in RESULT; references to '%s' "
4765- " inside the function will be considered as references to the "
4766- " result only" _warn_en_US,
4784+ " The function name should not appear in RESULT; references to '%s' inside the function will be considered as references to the result only" _warn_en_US,
47674785 name.source );
47684786 // RESULT name was ignored above, the only side effect from doing so will be
47694787 // the inability to make recursive calls. The related parser::Name is still
@@ -5074,8 +5092,7 @@ bool SubprogramVisitor::BeginSubprogram(const parser::Name &name,
50745092 if (hasModulePrefix && !currScope ().IsModule () &&
50755093 !currScope ().IsSubmodule ()) { // C1547
50765094 Say (name,
5077- " '%s' is a MODULE procedure which must be declared within a "
5078- " MODULE or SUBMODULE" _err_en_US);
5095+ " '%s' is a MODULE procedure which must be declared within a MODULE or SUBMODULE" _err_en_US);
50795096 // Don't return here because it can be useful to have the scope set for
50805097 // other semantic checks run before we print the errors
50815098 isValid = false ;
@@ -5196,9 +5213,10 @@ bool SubprogramVisitor::HandlePreviousCalls(
51965213 }
51975214}
51985215
5199- void SubprogramVisitor::CheckExtantProc (
5216+ const Symbol * SubprogramVisitor::CheckExtantProc (
52005217 const parser::Name &name, Symbol::Flag subpFlag) {
5201- if (auto *prev{FindSymbol (name)}) {
5218+ Symbol *prev{FindSymbol (name)};
5219+ if (prev) {
52025220 if (IsDummy (*prev)) {
52035221 } else if (auto *entity{prev->detailsIf <EntityDetails>()};
52045222 IsPointer (*prev) && entity && !entity->type ()) {
@@ -5210,12 +5228,15 @@ void SubprogramVisitor::CheckExtantProc(
52105228 SayAlreadyDeclared (name, *prev);
52115229 }
52125230 }
5231+ return prev;
52135232}
52145233
52155234Symbol &SubprogramVisitor::PushSubprogramScope (const parser::Name &name,
52165235 Symbol::Flag subpFlag, const parser::LanguageBindingSpec *bindingSpec,
52175236 bool hasModulePrefix) {
52185237 Symbol *symbol{GetSpecificFromGeneric (name)};
5238+ const DeclTypeSpec *previousImplicitType{nullptr };
5239+ SourceName previousName;
52195240 if (!symbol) {
52205241 if (bindingSpec && currScope ().IsGlobal () &&
52215242 std::get<std::optional<parser::ScalarDefaultCharConstantExpr>>(
@@ -5228,14 +5249,25 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
52285249 &MakeSymbol (context ().GetTempName (currScope ()), Attrs{},
52295250 MiscDetails{MiscDetails::Kind::ScopeName}));
52305251 }
5231- CheckExtantProc (name, subpFlag);
5252+ if (const Symbol *previous{CheckExtantProc (name, subpFlag)}) {
5253+ if (previous->test (Symbol::Flag::Function) &&
5254+ previous->test (Symbol::Flag::Implicit)) {
5255+ // Function was implicitly typed in previous compilation unit.
5256+ previousImplicitType = previous->GetType ();
5257+ previousName = previous->name ();
5258+ }
5259+ }
52325260 symbol = &MakeSymbol (name, SubprogramDetails{});
52335261 }
52345262 symbol->ReplaceName (name.source );
52355263 symbol->set (subpFlag);
52365264 PushScope (Scope::Kind::Subprogram, symbol);
52375265 if (subpFlag == Symbol::Flag::Function) {
5238- funcResultStack ().Push (currScope (), name.source );
5266+ auto &funcResultTop{funcResultStack ().Push (currScope (), name.source )};
5267+ funcResultTop.previousImplicitType = previousImplicitType;
5268+ ;
5269+ funcResultTop.previousName = previousName;
5270+ ;
52395271 }
52405272 if (inInterfaceBlock ()) {
52415273 auto &details{symbol->get <SubprogramDetails>()};
@@ -8669,11 +8701,6 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
86698701 x.u );
86708702}
86718703
8672- static bool TypesMismatchIfNonNull (
8673- const DeclTypeSpec *type1, const DeclTypeSpec *type2) {
8674- return type1 && type2 && *type1 != *type2;
8675- }
8676-
86778704// If implicit types are allowed, ensure name is in the symbol table.
86788705// Otherwise, report an error if it hasn't been declared.
86798706const parser::Name *DeclarationVisitor::ResolveName (const parser::Name &name) {
0 commit comments