[flang-commits] [flang] 1eb9948 - [flang] Catch more bad DATA statement objects

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Mar 27 16:10:12 PDT 2023


Author: Peter Klausler
Date: 2023-03-27T16:10:03-07:00
New Revision: 1eb9948f02560912c67757e18d105d18609935ce

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

LOG: [flang] Catch more bad DATA statement objects

The data statement variable checker is missing some cases, like expressions
that are not variables.  Run the checker first to enjoy its very specific
error messages, but when it finds no problems, still apply a general
check that an expression is a "variable" and also not a constant expression
at the top level as a backstop.

Differential Revision: https://reviews.llvm.org/D146580

Added: 
    

Modified: 
    flang/lib/Semantics/check-data.cpp
    flang/test/Semantics/data03.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp
index 955998bedc0c..f33258ea7c19 100644
--- a/flang/lib/Semantics/check-data.cpp
+++ b/flang/lib/Semantics/check-data.cpp
@@ -179,24 +179,27 @@ class DataVarChecker : public evaluate::AllTraverse<DataVarChecker, true> {
   bool isFirstSymbol_{true};
 };
 
+static bool IsValidDataObject(const SomeExpr &expr) { // C878, C879
+  return !evaluate::IsConstantExpr(expr) &&
+      (evaluate::IsVariable(expr) || evaluate::IsProcedurePointer(expr));
+}
+
 void DataChecker::Leave(const parser::DataIDoObject &object) {
   if (const auto *designator{
           std::get_if<parser::Scalar<common::Indirection<parser::Designator>>>(
               &object.u)}) {
     if (MaybeExpr expr{exprAnalyzer_.Analyze(*designator)}) {
       auto source{designator->thing.value().source};
-      if (evaluate::IsConstantExpr(*expr)) { // C878,C879
-        exprAnalyzer_.context().Say(
-            source, "Data implied do object must be a variable"_err_en_US);
-      } else {
-        DataVarChecker checker{exprAnalyzer_.context(), source};
-        if (checker(*expr)) {
-          if (checker.HasComponentWithoutSubscripts()) { // C880
-            exprAnalyzer_.context().Say(source,
-                "Data implied do structure component must be subscripted"_err_en_US);
-          } else {
-            return;
-          }
+      DataVarChecker checker{exprAnalyzer_.context(), source};
+      if (checker(*expr)) {
+        if (checker.HasComponentWithoutSubscripts()) { // C880
+          exprAnalyzer_.context().Say(source,
+              "Data implied do structure component must be subscripted"_err_en_US);
+        } else if (!IsValidDataObject(*expr)) {
+          exprAnalyzer_.context().Say(
+              source, "Data implied do object must be a variable"_err_en_US);
+        } else {
+          return;
         }
       }
     }
@@ -211,9 +214,13 @@ void DataChecker::Leave(const parser::DataStmtObject &dataObject) {
           },
           [&](const auto &var) {
             auto expr{exprAnalyzer_.Analyze(var)};
+            auto source{parser::FindSourceLocation(dataObject)};
             if (!expr ||
-                !DataVarChecker{exprAnalyzer_.context(),
-                    parser::FindSourceLocation(dataObject)}(*expr)) {
+                !DataVarChecker{exprAnalyzer_.context(), source}(*expr)) {
+              currentSetHasFatalErrors_ = true;
+            } else if (!IsValidDataObject(*expr)) {
+              exprAnalyzer_.context().Say(
+                  source, "Data statement object must be a variable"_err_en_US);
               currentSetHasFatalErrors_ = true;
             }
           },

diff  --git a/flang/test/Semantics/data03.f90 b/flang/test/Semantics/data03.f90
index b3ed3382036f..d9bead778433 100644
--- a/flang/test/Semantics/data03.f90
+++ b/flang/test/Semantics/data03.f90
@@ -1,5 +1,5 @@
 ! RUN: %python %S/test_errors.py %s %flang_fc1
-!Testing data constraints : C874 - C875, C878 - C881 
+!Testing data constraints : C874 - C875, C878 - C881
 module m
     integer, target :: modarray(1)
   contains
@@ -8,7 +8,7 @@ function f(i)
       integer, pointer :: f
       f => modarray(i)
     end
-    subroutine CheckObject 
+    subroutine CheckObject
       type specialNumbers
         integer one
         integer numbers(5)
@@ -34,6 +34,8 @@ subroutine CheckObject
       integer :: d(10, 10)
       character :: name(12)
       integer :: ind = 2
+      !ERROR: Data statement object must be a variable
+      DATA name%len / 666 /
       !C874
       !ERROR: Data object must not be a coindexed variable
       DATA a[1] / 1 /
@@ -77,7 +79,7 @@ subroutine CheckObject
       !C881
       !ERROR: Data object must have constant subscripts
       DATA(b(x), i = 1, 5) / 5 * 1 /
-      !C881 
+      !C881
       !OK: Correct use
       DATA(nums % numbers(i), i = 1, 5) / 5 * 1 /
       !C881
@@ -86,5 +88,5 @@ subroutine CheckObject
       !C881
       !OK: Correct use
       DATA(d(i, 1), i = 1, 10) / 10 * 1 /
-    end 
+    end
   end


        


More information about the flang-commits mailing list