[flang-commits] [flang] c1c0121 - [flang]Implemented Semantic Checkes for 5 data constraints

Anchu Rajendran via flang-commits flang-commits at lists.llvm.org
Fri Apr 17 23:56:51 PDT 2020


Author: Anchu Rajendran
Date: 2020-04-18T12:21:30+05:30
New Revision: c1c01212c49a0792c0594662db84be271e29cba6

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

LOG: [flang]Implemented Semantic Checkes for 5 data constraints

Summary:
 C874, C875, C878, C880 and C881 checks are implemented.

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

Added: 
    flang/test/Semantics/data03.f90

Modified: 
    flang/lib/Semantics/check-data.cpp
    flang/lib/Semantics/check-data.h

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-data.cpp b/flang/lib/Semantics/check-data.cpp
index 6178eb7360ca..c1cc880583de 100644
--- a/flang/lib/Semantics/check-data.cpp
+++ b/flang/lib/Semantics/check-data.cpp
@@ -10,6 +10,59 @@
 
 namespace Fortran::semantics {
 
+template <typename T> void DataChecker::CheckIfConstantSubscript(const T &x) {
+  evaluate::ExpressionAnalyzer exprAnalyzer{context_};
+  if (MaybeExpr checked{exprAnalyzer.Analyze(x)}) {
+    if (!evaluate::IsConstantExpr(*checked)) { // C875,C881
+      context_.Say(parser::FindSourceLocation(x),
+          "Data object must have constant bounds"_err_en_US);
+    }
+  }
+}
+
+void DataChecker::CheckSubscript(const parser::SectionSubscript &subscript) {
+  std::visit(common::visitors{
+                 [&](const parser::SubscriptTriplet &triplet) {
+                   CheckIfConstantSubscript(std::get<0>(triplet.t));
+                   CheckIfConstantSubscript(std::get<1>(triplet.t));
+                   CheckIfConstantSubscript(std::get<2>(triplet.t));
+                 },
+                 [&](const parser::IntExpr &intExpr) {
+                   CheckIfConstantSubscript(intExpr);
+                 },
+             },
+      subscript.u);
+}
+
+// Returns false if  DataRef has no subscript
+bool DataChecker::CheckAllSubscriptsInDataRef(
+    const parser::DataRef &dataRef, parser::CharBlock source) {
+  return std::visit(
+      common::visitors{
+          [&](const parser::Name &) { return false; },
+          [&](const common::Indirection<parser::StructureComponent>
+                  &structureComp) {
+            return CheckAllSubscriptsInDataRef(
+                structureComp.value().base, source);
+          },
+          [&](const common::Indirection<parser::ArrayElement> &arrayElem) {
+            for (auto &subscript : arrayElem.value().subscripts) {
+              CheckSubscript(subscript);
+            }
+            CheckAllSubscriptsInDataRef(arrayElem.value().base, source);
+            return true;
+          },
+          [&](const common::Indirection<parser::CoindexedNamedObject>
+                  &coindexedObj) { // C874
+            context_.Say(source,
+                "Data object must not be a coindexed variable"_err_en_US);
+            CheckAllSubscriptsInDataRef(coindexedObj.value().base, source);
+            return true;
+          },
+      },
+      dataRef.u);
+}
+
 void DataChecker::Leave(const parser::DataStmtConstant &dataConst) {
   if (auto *structure{
           std::get_if<parser::StructureConstructor>(&dataConst.u)}) {
@@ -25,10 +78,44 @@ void DataChecker::Leave(const parser::DataStmtConstant &dataConst) {
       }
     }
   }
-  // TODO: C886 and C887 for data-stmt-constant
 }
 
-// TODO: C874-C881
+// TODO: C876, C877, C879
+void DataChecker::Leave(const parser::DataImpliedDo &dataImpliedDo) {
+  for (const auto &object :
+      std::get<std::list<parser::DataIDoObject>>(dataImpliedDo.t)) {
+    if (const auto *designator{parser::Unwrap<parser::Designator>(object)}) {
+      if (auto *dataRef{std::get_if<parser::DataRef>(&designator->u)}) {
+        evaluate::ExpressionAnalyzer exprAnalyzer{context_};
+        if (MaybeExpr checked{exprAnalyzer.Analyze(*dataRef)}) {
+          if (evaluate::IsConstantExpr(*checked)) { // C878
+            context_.Say(designator->source,
+                "Data implied do object must be a variable"_err_en_US);
+          }
+        }
+        if (!CheckAllSubscriptsInDataRef(*dataRef,
+                designator->source)) { // C880
+          context_.Say(designator->source,
+              "Data implied do object must be subscripted"_err_en_US);
+        }
+      }
+    }
+  }
+}
+
+void DataChecker::Leave(const parser::DataStmtObject &dataObject) {
+  if (std::get_if<common::Indirection<parser::Variable>>(&dataObject.u)) {
+    if (const auto *designator{
+            parser::Unwrap<parser::Designator>(dataObject)}) {
+      if (auto *dataRef{std::get_if<parser::DataRef>(&designator->u)}) {
+        CheckAllSubscriptsInDataRef(*dataRef, designator->source);
+      }
+    } else { // C875
+      context_.Say(parser::FindSourceLocation(dataObject),
+          "Data object variable must not be a function reference"_err_en_US);
+    }
+  }
+}
 
 void DataChecker::Leave(const parser::DataStmtRepeat &dataRepeat) {
   if (const auto *designator{parser::Unwrap<parser::Designator>(dataRepeat)}) {

diff  --git a/flang/lib/Semantics/check-data.h b/flang/lib/Semantics/check-data.h
index 5d66c8e74e55..6624574fe921 100644
--- a/flang/lib/Semantics/check-data.h
+++ b/flang/lib/Semantics/check-data.h
@@ -20,9 +20,14 @@ class DataChecker : public virtual BaseChecker {
   DataChecker(SemanticsContext &context) : context_{context} {}
   void Leave(const parser::DataStmtRepeat &);
   void Leave(const parser::DataStmtConstant &);
+  void Leave(const parser::DataStmtObject &);
+  void Leave(const parser::DataImpliedDo &);
 
 private:
   SemanticsContext &context_;
+  template <typename T> void CheckIfConstantSubscript(const T &);
+  void CheckSubscript(const parser::SectionSubscript &);
+  bool CheckAllSubscriptsInDataRef(const parser::DataRef &, parser::CharBlock);
 };
 } // namespace Fortran::semantics
 #endif // FORTRAN_SEMANTICS_CHECK_DATA_H_

diff  --git a/flang/test/Semantics/data03.f90 b/flang/test/Semantics/data03.f90
new file mode 100644
index 000000000000..6548c047e438
--- /dev/null
+++ b/flang/test/Semantics/data03.f90
@@ -0,0 +1,83 @@
+! RUN: %B/test/Semantics/test_errors.sh %s %flang %t
+!Testing data constraints : C874 - C875, C878 - C881 
+module m
+  contains
+    function f(i)
+      integer ::i
+      integer ::result
+      result = i *1024 
+    end
+    subroutine CheckObject 
+      type specialNumbers
+        integer one
+        integer numbers(5)
+      end type
+      type large
+        integer elt(10)
+        integer val
+        type(specialNumbers) nums
+        type(specialNumbers) numsArray(5)
+      end type
+      type(specialNumbers), parameter ::newNums = &
+              specialNumbers(1, (/ 1, 2, 3, 4, 5 /))
+      type(specialNumbers), parameter ::newNumsArray(2) = &
+              (/ SpecialNumbers(1, (/ 1, 2, 3, 4, 5 /)), &
+              SpecialNumbers(1, (/ 1, 2, 3,4, 5 /)) /)
+      type(specialNumbers) nums
+      type(large) largeArray(5)
+      type(large) largeNumber
+      real :: a[*]
+      real :: b(5)
+      integer :: x
+      real, parameter:: c(5) = (/ 1, 2, 3, 4, 5 /)
+      integer :: d(10, 10)
+      character :: name(12)
+      integer :: ind = 2
+      !C874
+      !ERROR: Data object must not be a coindexed variable
+      DATA a[1] / 1 /
+      !C874
+      !ERROR: Data object must not be a coindexed variable
+      DATA(a[i], i = 1, 5) / 5 * 1 /
+      !C875
+      !ERROR: Data object variable must not be a function reference
+      DATA f(1) / 1 / 
+      !C875
+      !ERROR: Data object must have constant bounds
+      DATA b(ind) / 1 /
+      !C875
+      !ERROR: Data object must have constant bounds
+      DATA name( : ind) / 'Ancd' /
+      !C875
+      !ERROR: Data object must have constant bounds
+      DATA name(ind:) / 'Ancd' /
+      !C878
+      !ERROR: Data implied do object must be a variable
+      DATA(c(i), i = 1, 5) / 5 * 1 /
+      !C878
+      !ERROR: Data implied do object must be a variable
+      DATA(newNumsArray(i), i = 1, 2) &
+              / specialNumbers(1, 2 * (/ 1, 2, 3, 4, 5 /)) /
+      !C880
+      !ERROR: Data implied do object must be subscripted
+      DATA(nums % one, i = 1, 5) / 5 * 1 /
+      !C880
+      !OK: Correct use
+      DATA(largeArray(j) % nums % one, j = 1, 10) / 10 * 1 /
+      !C880
+      !OK: Correct use
+      DATA(largeNumber % numsArray(j) % one, j = 1, 10) / 10 * 1 /
+      !C881
+      !ERROR: Data object must have constant bounds
+      DATA(b(x), i = 1, 5) / 5 * 1 /
+      !C881 
+      !OK: Correct use
+      DATA(nums % numbers(i), i = 1, 5) / 5 * 1 /
+      !C881
+      !OK: Correct use
+      DATA((d(i, j), i = 1, 10), j = 1, 10) / 100 * 1 /
+      !C881
+      !OK: Correct use
+      DATA(d(i, 1), i = 1, 10) / 10 * 1 /
+    end 
+  end


        


More information about the flang-commits mailing list