Index: flang/docs/Extensions.md =================================================================== --- flang/docs/Extensions.md +++ flang/docs/Extensions.md @@ -283,6 +283,8 @@ * When a name is brought into a scope by multiple ways, such as USE-association as well as an `IMPORT` from its host, it's an error only if the resolution is ambiguous. +* An entity may appear in a `DATA` statement before its explicit + type declaration under `IMPLICIT NONE(TYPE)`. ### Extensions supported when enabled by options Index: flang/include/flang/Common/Fortran-features.h =================================================================== --- flang/include/flang/Common/Fortran-features.h +++ flang/include/flang/Common/Fortran-features.h @@ -36,7 +36,8 @@ ForwardRefImplicitNone, OpenAccessAppend, BOZAsDefaultInteger, DistinguishableSpecifics, DefaultSave, PointerInSeqType, NonCharacterFormat, SaveMainProgram, SaveBigMainProgramVariables, - DistinctArrayConstructorLengths, PPCVector, RelaxedIntentInChecking) + DistinctArrayConstructorLengths, PPCVector, RelaxedIntentInChecking, + ForwardRefImplicitNoneData) // Portability and suspicious usage warnings for conforming code ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable, Index: flang/lib/Semantics/resolve-names.cpp =================================================================== --- flang/lib/Semantics/resolve-names.cpp +++ flang/lib/Semantics/resolve-names.cpp @@ -697,6 +697,7 @@ bool CheckPossibleBadForwardRef(const Symbol &); bool inSpecificationPart_{false}; + bool inDataStmtObject_{false}; bool inEquivalenceStmt_{false}; // Some information is collected from a specification part for deferred @@ -2480,6 +2481,9 @@ // or object, it'll be caught later. return; } + if (inDataStmtObject_) { + return; + } if (!context().HasError(symbol)) { Say(symbol.name(), "No explicit type declared for '%s'"_err_en_US); context().SetError(symbol); @@ -2653,7 +2657,7 @@ } void ScopeHandler::NotePossibleBadForwardRef(const parser::Name &name) { - if (inSpecificationPart_ && name.symbol) { + if (inSpecificationPart_ && !inDataStmtObject_ && name.symbol) { auto kind{currScope().kind()}; if ((kind == Scope::Kind::Subprogram && !currScope().IsStmtFunction()) || kind == Scope::Kind::BlockConstruct) { @@ -6271,6 +6275,12 @@ } auto *prevType{symbol.GetType()}; if (!prevType) { + if (symbol.test(Symbol::Flag::InDataStmt) && isImplicitNoneType() && + context().ShouldWarn( + common::LanguageFeature::ForwardRefImplicitNoneData)) { + Say(name, + "'%s' appeared in a DATA statement before its type was declared under IMPLICIT NONE(TYPE)"_port_en_US); + } symbol.SetType(type); } else if (symbol.has()) { // error recovery case, redeclaration of use-associated name @@ -6632,6 +6642,7 @@ auto flagRestorer{common::ScopedSet(inSpecificationPart_, false)}; common::visit(common::visitors{ [&](const Indirection &y) { + auto restorer{common::ScopedSet(inDataStmtObject_, true)}; Walk(y.value()); const parser::Name &first{ parser::GetFirstName(y.value())}; @@ -7189,7 +7200,7 @@ } return &name; } - if (isImplicitNoneType()) { + if (isImplicitNoneType() && !inDataStmtObject_) { Say(name, "No explicit type declared for '%s'"_err_en_US); return nullptr; } Index: flang/test/Semantics/resolve30.f90 =================================================================== --- flang/test/Semantics/resolve30.f90 +++ flang/test/Semantics/resolve30.f90 @@ -1,4 +1,4 @@ -! RUN: %python %S/test_errors.py %s %flang_fc1 +! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic subroutine s1 integer x block @@ -37,3 +37,10 @@ !ERROR: Must have INTEGER type, but is REAL(4) data(b(j), j=1, 16) / 16 * 0.0 / end + +subroutine s5 + implicit none + data x/1./ + !PORTABILITY: 'x' appeared in a DATA statement before its type was declared under IMPLICIT NONE(TYPE) + real x +end