[flang] Enforce limit on rank + corank
authorPeter Klausler <pklausler@nvidia.com>
Fri, 29 Apr 2022 20:23:26 +0000 (13:23 -0700)
committerPeter Klausler <pklausler@nvidia.com>
Tue, 10 May 2022 15:53:08 +0000 (08:53 -0700)
Fortran 2018 requires that a compiler allow objects whose rank + corank
is 15, and that's our maximum; detect and diagnose violations.

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

flang/include/flang/Evaluate/real.h
flang/lib/Semantics/check-declarations.cpp
flang/test/Semantics/maxrank.f90 [new file with mode: 0644]

index 4e99269..2b5562a 100644 (file)
@@ -135,10 +135,6 @@ public:
   ValueWithRealFlags<Real> MODULO(
       const Real &, Rounding rounding = defaultRounding) const;
 
-  // DIM(X,Y) = MAX(X-Y, 0)
-  ValueWithRealFlags<Real> DIM(
-      const Real &, Rounding rounding = defaultRounding) const;
-
   template <typename INT> constexpr INT EXPONENT() const {
     if (Exponent() == maxExponent) {
       return INT::HUGE();
index 42fa416..c92a8dd 100644 (file)
@@ -457,6 +457,17 @@ void CheckHelper::CheckObjectEntity(
   CheckArraySpec(symbol, details.shape());
   Check(details.shape());
   Check(details.coshape());
+  if (details.shape().Rank() > common::maxRank) {
+    messages_.Say(
+        "'%s' has rank %d, which is greater than the maximum supported rank %d"_err_en_US,
+        symbol.name(), details.shape().Rank(), common::maxRank);
+  } else if (details.shape().Rank() + details.coshape().Rank() >
+      common::maxRank) {
+    messages_.Say(
+        "'%s' has rank %d and corank %d, whose sum is greater than the maximum supported rank %d"_err_en_US,
+        symbol.name(), details.shape().Rank(), details.coshape().Rank(),
+        common::maxRank);
+  }
   CheckAssumedTypeEntity(symbol, details);
   WarnMissingFinal(symbol);
   if (!details.coshape().empty()) {
diff --git a/flang/test/Semantics/maxrank.f90 b/flang/test/Semantics/maxrank.f90
new file mode 100644 (file)
index 0000000..ea3ece9
--- /dev/null
@@ -0,0 +1,31 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Enforce limits on rank + corank
+module m
+  !ERROR: 'x' has rank 16, which is greater than the maximum supported rank 15
+  real :: x(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
+  !ERROR: 'y' has rank 16, which is greater than the maximum supported rank 15
+  real, allocatable :: y(:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:)
+  !ERROR: 'z' has rank 16, which is greater than the maximum supported rank 15
+  real, pointer :: z(:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:)
+  !ERROR: 'w' has rank 16, which is greater than the maximum supported rank 15
+  real, dimension(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) :: w
+  !ERROR: 'a' has rank 15 and corank 1, whose sum is greater than the maximum supported rank 15
+  real :: a(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)[*]
+  !ERROR: 'b' has rank 14 and corank 2, whose sum is greater than the maximum supported rank 15
+  real :: b(1,1,1,1,1,1,1,1,1,1,1,1,1,1)[1,*]
+  !ERROR: 'c' has rank 14 and corank 2, whose sum is greater than the maximum supported rank 15
+  real :: c
+  dimension :: c(1,1,1,1,1,1,1,1,1,1,1,1,1,1)
+  codimension :: c[1,*]
+  interface
+    !ERROR: 'foo' has rank 16, which is greater than the maximum supported rank 15
+    real function foo()
+      dimension :: foo(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
+    end function
+  end interface
+ contains
+  function bar() result(res)
+    !ERROR: 'res' has rank 16, which is greater than the maximum supported rank 15
+    real :: res(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
+  end function
+end module