[flang-commits] [flang] df11165 - [flang] Extension: allow DATA to precede declaration under IMPLICIT NONE(TYPE)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Jul 17 12:45:37 PDT 2023


Author: Peter Klausler
Date: 2023-07-17T12:35:12-07:00
New Revision: df111658a2535d273a4d7d1edf7c412e090ac97e

URL: https://github.com/llvm/llvm-project/commit/df111658a2535d273a4d7d1edf7c412e090ac97e
DIFF: https://github.com/llvm/llvm-project/commit/df111658a2535d273a4d7d1edf7c412e090ac97e.diff

LOG: [flang] Extension: allow DATA to precede declaration under IMPLICIT NONE(TYPE)

It is not standard conforming under IMPLICIT NONE(TYPE) for a name to
appear in a DATA statement prior to its explicit type declaration,
but it is benign, supported in other compilers, and attested in real
applications.  Support it with an optional portability warning.

Fixes GitHub LLVM bug https://github.com/llvm/llvm-project/issues/63783.

Added: 
    

Modified: 
    flang/docs/Extensions.md
    flang/include/flang/Common/Fortran-features.h
    flang/lib/Semantics/resolve-names.cpp
    flang/test/Semantics/resolve30.f90

Removed: 
    


################################################################################
diff  --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index d3cb2f142c54b0..bb9c0ebe84a16a 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -283,6 +283,8 @@ end
 * 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
 

diff  --git a/flang/include/flang/Common/Fortran-features.h b/flang/include/flang/Common/Fortran-features.h
index 3539c9aeab5763..5cbe1d6e157f2f 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -36,7 +36,8 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
     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,

diff  --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index dfff0458fec456..3afba79781a05f 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -697,6 +697,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
   bool CheckPossibleBadForwardRef(const Symbol &);
 
   bool inSpecificationPart_{false};
+  bool inDataStmtObject_{false};
   bool inEquivalenceStmt_{false};
 
   // Some information is collected from a specification part for deferred
@@ -2481,6 +2482,9 @@ void ScopeHandler::ApplyImplicitRules(
     // 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);
@@ -2654,7 +2658,7 @@ const DeclTypeSpec &ScopeHandler::MakeLogicalType(int kind) {
 }
 
 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) {
@@ -6281,6 +6285,12 @@ void DeclarationVisitor::SetType(
   }
   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<UseDetails>()) {
     // error recovery case, redeclaration of use-associated name
@@ -6642,6 +6652,7 @@ bool ConstructVisitor::Pre(const parser::DataStmtObject &x) {
   auto flagRestorer{common::ScopedSet(inSpecificationPart_, false)};
   common::visit(common::visitors{
                     [&](const Indirection<parser::Variable> &y) {
+                      auto restorer{common::ScopedSet(inDataStmtObject_, true)};
                       Walk(y.value());
                       const parser::Name &first{
                           parser::GetFirstName(y.value())};
@@ -7199,7 +7210,7 @@ const parser::Name *DeclarationVisitor::ResolveName(const parser::Name &name) {
     }
     return &name;
   }
-  if (isImplicitNoneType()) {
+  if (isImplicitNoneType() && !inDataStmtObject_) {
     Say(name, "No explicit type declared for '%s'"_err_en_US);
     return nullptr;
   }

diff  --git a/flang/test/Semantics/resolve30.f90 b/flang/test/Semantics/resolve30.f90
index c594cceef15b1f..32108e89cdefe8 100644
--- a/flang/test/Semantics/resolve30.f90
+++ b/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 @@ subroutine s4
   !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


        


More information about the flang-commits mailing list