[flang-commits] [flang] [flang] Warn about automatic data in main program, disallow in BLOCK … (PR #102045)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Aug 5 12:40:57 PDT 2024


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/102045

…DATA

We allow automatic data objects in the specification part of the main program; add an optional portability warning and documentation.  Don't allow them in BLOCK DATA.  They're already disallowed as module variables.

>From 93636493a475545cc04e3bcdb7ff05617fe88d58 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 5 Aug 2024 12:36:57 -0700
Subject: [PATCH] [flang] Warn about automatic data in main program, disallow
 in BLOCK DATA

We allow automatic data objects in the specification part of the main program;
add an optional portability warning and documentation.  Don't allow them in
BLOCK DATA.  They're already disallowed as module variables.
---
 flang/docs/Extensions.md                      |  2 ++
 flang/include/flang/Common/Fortran-features.h |  2 +-
 flang/lib/Semantics/check-declarations.cpp    | 29 ++++++++++++++++---
 flang/test/Semantics/resolve77.f90            | 15 +++++++++-
 flang/test/Semantics/stmt-func01.f90          |  1 +
 5 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 093596c9dc8eb..fb57744c21570 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -384,6 +384,8 @@ end
 * `BIND(C, NAME="...", CDEFINED)` signifies that the storage for an
   interoperable variable will be allocated outside of Fortran,
   probably by a C or C++ external definition.
+* An automatic data object may be declared in the specification part
+  of the main program.
 
 ### 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 938da08e19d6b..518304191d63f 100644
--- a/flang/include/flang/Common/Fortran-features.h
+++ b/flang/include/flang/Common/Fortran-features.h
@@ -51,7 +51,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
     BadBranchTarget, ConvertedArgument, HollerithPolymorphic, ListDirectedSize,
     NonBindCInteroperability, CudaManaged, CudaUnified,
     PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
-    UndefinableAsynchronousOrVolatileActual)
+    UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram)
 
 // Portability and suspicious usage warnings
 ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
diff --git a/flang/lib/Semantics/check-declarations.cpp b/flang/lib/Semantics/check-declarations.cpp
index a52f013a70b9d..be0de5b4e03a4 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -247,6 +247,14 @@ void CheckHelper::Check(
   }
 }
 
+static bool IsBlockData(const Scope &scope) {
+  return scope.kind() == Scope::Kind::BlockData;
+}
+
+static bool IsBlockData(const Symbol &symbol) {
+  return symbol.scope() && IsBlockData(*symbol.scope());
+}
+
 void CheckHelper::Check(const Symbol &symbol) {
   if (symbol.name().size() > common::maxNameLen &&
       &symbol == &symbol.GetUltimate()) {
@@ -463,6 +471,23 @@ void CheckHelper::Check(const Symbol &symbol) {
       messages_.Say(
           "Automatic data object '%s' may not appear in a module"_err_en_US,
           symbol.name());
+    } else if (IsBlockData(symbol.owner())) {
+      messages_.Say(
+          "Automatic data object '%s' may not appear in a BLOCK DATA subprogram"_err_en_US,
+          symbol.name());
+    } else if (symbol.owner().kind() == Scope::Kind::MainProgram) {
+      if (context_.IsEnabled(common::LanguageFeature::AutomaticInMainProgram)) {
+        if (context_.ShouldWarn(
+                common::LanguageFeature::AutomaticInMainProgram)) {
+          messages_.Say(
+              "Automatic data object '%s' should not appear in the specification part of a main program"_port_en_US,
+              symbol.name());
+        }
+      } else {
+        messages_.Say(
+            "Automatic data object '%s' may not appear in the specification part of a main program"_err_en_US,
+            symbol.name());
+      }
     }
   }
   if (IsProcedure(symbol)) {
@@ -2799,10 +2824,6 @@ static bool IsSubprogramDefinition(const Symbol &symbol) {
       symbol.scope()->kind() == Scope::Kind::Subprogram;
 }
 
-static bool IsBlockData(const Symbol &symbol) {
-  return symbol.scope() && symbol.scope()->kind() == Scope::Kind::BlockData;
-}
-
 static bool IsExternalProcedureDefinition(const Symbol &symbol) {
   return IsBlockData(symbol) ||
       (IsSubprogramDefinition(symbol) &&
diff --git a/flang/test/Semantics/resolve77.f90 b/flang/test/Semantics/resolve77.f90
index ffee10271d51b..943993ee74d76 100644
--- a/flang/test/Semantics/resolve77.f90
+++ b/flang/test/Semantics/resolve77.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
 ! Tests valid and invalid usage of forward references to procedures
 ! in specification expressions.
 module m
@@ -56,3 +56,16 @@ pure integer function if2(n)
     if2 = n
   end function
 end subroutine
+
+block data
+  common /blk2/ n
+  data n/100/
+  !ERROR: Automatic data object 'a' may not appear in a BLOCK DATA subprogram
+  real a(n)
+end
+
+program main
+  common /blk2/ n
+  !PORTABILITY: Automatic data object 'a' should not appear in the specification part of a main program
+  real a(n)
+end
diff --git a/flang/test/Semantics/stmt-func01.f90 b/flang/test/Semantics/stmt-func01.f90
index 83c31ded1d39b..a87b0d7af52b4 100644
--- a/flang/test/Semantics/stmt-func01.f90
+++ b/flang/test/Semantics/stmt-func01.f90
@@ -10,6 +10,7 @@ program main
     pure integer function ifunc()
     end function
   end interface
+  !PORTABILITY: Automatic data object 'x1' should not appear in the specification part of a main program
   type(t1(k=4,l=ifunc())) x1
   !PORTABILITY: Statement function 'sf1' should not contain an array constructor
   sf1(n) = sum([(j,j=1,n)])



More information about the flang-commits mailing list