@@ -768,10 +768,22 @@ class ScopeHandler : public ImplicitRulesVisitor {
768768 deferImplicitTyping_ = skipImplicitTyping_ = skip;
769769 }
770770
771+ void NoteEarlyDeclaredDummyArgument (Symbol &symbol) {
772+ earlyDeclaredDummyArguments_.insert (symbol);
773+ }
774+ bool IsEarlyDeclaredDummyArgument (Symbol &symbol) {
775+ return earlyDeclaredDummyArguments_.find (symbol) !=
776+ earlyDeclaredDummyArguments_.end ();
777+ }
778+ void ForgetEarlyDeclaredDummyArgument (Symbol &symbol) {
779+ earlyDeclaredDummyArguments_.erase (symbol);
780+ }
781+
771782private:
772783 Scope *currScope_{nullptr };
773784 FuncResultStack funcResultStack_{*this };
774785 std::map<Scope *, DeferredDeclarationState> deferred_;
786+ UnorderedSymbolSet earlyDeclaredDummyArguments_;
775787};
776788
777789class ModuleVisitor : public virtual ScopeHandler {
@@ -1970,6 +1982,9 @@ class ResolveNamesVisitor : public virtual ScopeHandler,
19701982 Scope &topScope_;
19711983
19721984 void PreSpecificationConstruct (const parser::SpecificationConstruct &);
1985+ void EarlyDummyTypeDeclaration (
1986+ const parser::Statement<common::Indirection<parser::TypeDeclarationStmt>>
1987+ &);
19731988 void CreateCommonBlockSymbols (const parser::CommonStmt &);
19741989 void CreateObjectSymbols (const std::list<parser::ObjectDecl> &, Attr);
19751990 void CreateGeneric (const parser::GenericSpec &);
@@ -5605,6 +5620,7 @@ Symbol &DeclarationVisitor::DeclareUnknownEntity(
56055620 } else {
56065621 Symbol &symbol{DeclareEntity<EntityDetails>(name, attrs)};
56075622 if (auto *type{GetDeclTypeSpec ()}) {
5623+ ForgetEarlyDeclaredDummyArgument (symbol);
56085624 SetType (name, *type);
56095625 }
56105626 charInfo_.length .reset ();
@@ -5681,6 +5697,7 @@ Symbol &DeclarationVisitor::DeclareProcEntity(
56815697 symbol.set (Symbol::Flag::Subroutine);
56825698 }
56835699 } else if (auto *type{GetDeclTypeSpec ()}) {
5700+ ForgetEarlyDeclaredDummyArgument (symbol);
56845701 SetType (name, *type);
56855702 symbol.set (Symbol::Flag::Function);
56865703 }
@@ -5695,6 +5712,7 @@ Symbol &DeclarationVisitor::DeclareObjectEntity(
56955712 Symbol &symbol{DeclareEntity<ObjectEntityDetails>(name, attrs)};
56965713 if (auto *details{symbol.detailsIf <ObjectEntityDetails>()}) {
56975714 if (auto *type{GetDeclTypeSpec ()}) {
5715+ ForgetEarlyDeclaredDummyArgument (symbol);
56985716 SetType (name, *type);
56995717 }
57005718 if (!arraySpec ().empty ()) {
@@ -5705,9 +5723,11 @@ Symbol &DeclarationVisitor::DeclareObjectEntity(
57055723 context ().SetError (symbol);
57065724 }
57075725 } else if (MustBeScalar (symbol)) {
5708- context ().Warn (common::UsageWarning::PreviousScalarUse, name.source ,
5709- " '%s' appeared earlier as a scalar actual argument to a specification function" _warn_en_US,
5710- name.source );
5726+ if (!context ().HasError (symbol)) {
5727+ context ().Warn (common::UsageWarning::PreviousScalarUse, name.source ,
5728+ " '%s' appeared earlier as a scalar actual argument to a specification function" _warn_en_US,
5729+ name.source );
5730+ }
57115731 } else if (details->init () || symbol.test (Symbol::Flag::InDataStmt)) {
57125732 Say (name, " '%s' was initialized earlier as a scalar" _err_en_US);
57135733 } else {
@@ -8461,6 +8481,11 @@ const parser::Name *DeclarationVisitor::ResolveDataRef(
84618481 x.u );
84628482}
84638483
8484+ static bool TypesMismatchIfNonNull (
8485+ const DeclTypeSpec *type1, const DeclTypeSpec *type2) {
8486+ return type1 && type2 && *type1 != *type2;
8487+ }
8488+
84648489// If implicit types are allowed, ensure name is in the symbol table.
84658490// Otherwise, report an error if it hasn't been declared.
84668491const parser::Name *DeclarationVisitor::ResolveName (const parser::Name &name) {
@@ -8482,13 +8507,30 @@ const parser::Name *DeclarationVisitor::ResolveName(const parser::Name &name) {
84828507 symbol->set (Symbol::Flag::ImplicitOrError, false );
84838508 if (IsUplevelReference (*symbol)) {
84848509 MakeHostAssocSymbol (name, *symbol);
8485- } else if (IsDummy (*symbol) ||
8486- (!symbol->GetType () && FindCommonBlockContaining (*symbol))) {
8510+ } else if (IsDummy (*symbol)) {
84878511 CheckEntryDummyUse (name.source , symbol);
8512+ ConvertToObjectEntity (*symbol);
8513+ if (IsEarlyDeclaredDummyArgument (*symbol)) {
8514+ ForgetEarlyDeclaredDummyArgument (*symbol);
8515+ if (isImplicitNoneType ()) {
8516+ context ().Warn (common::LanguageFeature::ForwardRefImplicitNone,
8517+ name.source ,
8518+ " '%s' was used under IMPLICIT NONE(TYPE) before being explicitly typed" _warn_en_US,
8519+ name.source );
8520+ } else if (TypesMismatchIfNonNull (
8521+ symbol->GetType (), GetImplicitType (*symbol))) {
8522+ context ().Warn (common::LanguageFeature::ForwardRefExplicitTypeDummy,
8523+ name.source ,
8524+ " '%s' was used before being explicitly typed (and its implicit type would differ)" _warn_en_US,
8525+ name.source );
8526+ }
8527+ }
8528+ ApplyImplicitRules (*symbol);
8529+ } else if (!symbol->GetType () && FindCommonBlockContaining (*symbol)) {
84888530 ConvertToObjectEntity (*symbol);
84898531 ApplyImplicitRules (*symbol);
84908532 } else if (const auto *tpd{symbol->detailsIf <TypeParamDetails>()};
8491- tpd && !tpd->attr ()) {
8533+ tpd && !tpd->attr ()) {
84928534 Say (name,
84938535 " Type parameter '%s' was referenced before being declared" _err_en_US,
84948536 name.source );
@@ -9031,11 +9073,6 @@ static bool IsLocallyImplicitGlobalSymbol(
90319073 return false ;
90329074}
90339075
9034- static bool TypesMismatchIfNonNull (
9035- const DeclTypeSpec *type1, const DeclTypeSpec *type2) {
9036- return type1 && type2 && *type1 != *type2;
9037- }
9038-
90399076// Check and set the Function or Subroutine flag on symbol; false on error.
90409077bool ResolveNamesVisitor::SetProcFlag (
90419078 const parser::Name &name, Symbol &symbol, Symbol::Flag flag) {
@@ -9252,6 +9289,10 @@ void ResolveNamesVisitor::PreSpecificationConstruct(
92529289 const parser::SpecificationConstruct &spec) {
92539290 common::visit (
92549291 common::visitors{
9292+ [&](const parser::Statement<
9293+ common::Indirection<parser::TypeDeclarationStmt>> &y) {
9294+ EarlyDummyTypeDeclaration (y);
9295+ },
92559296 [&](const parser::Statement<Indirection<parser::GenericStmt>> &y) {
92569297 CreateGeneric (std::get<parser::GenericSpec>(y.statement .value ().t ));
92579298 },
@@ -9280,6 +9321,44 @@ void ResolveNamesVisitor::PreSpecificationConstruct(
92809321 spec.u );
92819322}
92829323
9324+ void ResolveNamesVisitor::EarlyDummyTypeDeclaration (
9325+ const parser::Statement<common::Indirection<parser::TypeDeclarationStmt>>
9326+ &stmt) {
9327+ context ().set_location (stmt.source );
9328+ const auto &[declTypeSpec, attrs, entities] = stmt.statement .value ().t ;
9329+ if (const auto *intrin{
9330+ std::get_if<parser::IntrinsicTypeSpec>(&declTypeSpec.u )}) {
9331+ if (const auto *intType{std::get_if<parser::IntegerTypeSpec>(&intrin->u )}) {
9332+ if (const auto &kind{intType->v }) {
9333+ if (!parser::Unwrap<parser::KindSelector::StarSize>(*kind) &&
9334+ !parser::Unwrap<parser::IntLiteralConstant>(*kind)) {
9335+ return ;
9336+ }
9337+ }
9338+ const DeclTypeSpec *type{nullptr };
9339+ for (const auto &ent : entities) {
9340+ const auto &objName{std::get<parser::ObjectName>(ent.t )};
9341+ Resolve (objName, FindInScope (currScope (), objName));
9342+ if (Symbol * symbol{objName.symbol };
9343+ symbol && IsDummy (*symbol) && NeedsType (*symbol)) {
9344+ if (!type) {
9345+ type = ProcessTypeSpec (declTypeSpec);
9346+ if (!type || !type->IsNumeric (TypeCategory::Integer)) {
9347+ break ;
9348+ }
9349+ }
9350+ symbol->SetType (*type);
9351+ NoteEarlyDeclaredDummyArgument (*symbol);
9352+ // Set the Implicit flag to disable bogus errors from
9353+ // being emitted later when this declaration is processed
9354+ // again normally.
9355+ symbol->set (Symbol::Flag::Implicit);
9356+ }
9357+ }
9358+ }
9359+ }
9360+ }
9361+
92839362void ResolveNamesVisitor::CreateCommonBlockSymbols (
92849363 const parser::CommonStmt &commonStmt) {
92859364 for (const parser::CommonStmt::Block &block : commonStmt.blocks ) {
0 commit comments