[flang] Avoid spurious error message in function result compatibility
authorPeter Klausler <pklausler@nvidia.com>
Thu, 18 Aug 2022 17:44:50 +0000 (10:44 -0700)
committerPeter Klausler <pklausler@nvidia.com>
Thu, 18 Aug 2022 21:58:16 +0000 (14:58 -0700)
When checking function interface compatibility for procedure pointer
assignment/initialization or actual/dummy procedure association, don't
emit a diagnositic about function result shape incompatibility unless
the interfaces differ in rank or have distinct constant extents on a
dimension.  Function results whose dimensions are determined by dummy
arguments or host-associated variables are not necessarily incompatible.

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

flang/lib/Evaluate/characteristics.cpp

index a2cc866..25de823 100644 (file)
@@ -875,6 +875,23 @@ bool FunctionResult::CanBeReturnedViaImplicitInterface() const {
   }
 }
 
+static bool AreCompatibleFunctionResultShapes(const Shape &x, const Shape &y) {
+  int rank{GetRank(x)};
+  if (GetRank(y) != rank) {
+    return false;
+  }
+  for (int j{0}; j < rank; ++j) {
+    if (auto xDim{ToInt64(x[j])}) {
+      if (auto yDim{ToInt64(y[j])}) {
+        if (*xDim != *yDim) {
+          return false;
+        }
+      }
+    }
+  }
+  return true;
+}
+
 bool FunctionResult::IsCompatibleWith(
     const FunctionResult &actual, std::string *whyNot) const {
   Attrs actualAttrs{actual.attrs};
@@ -892,9 +909,10 @@ bool FunctionResult::IsCompatibleWith(
           *whyNot = "function results have distinct ranks";
         }
       } else if (!attrs.test(Attr::Allocatable) && !attrs.test(Attr::Pointer) &&
-          ifaceTypeShape->shape() != actualTypeShape->shape()) {
+          !AreCompatibleFunctionResultShapes(
+              ifaceTypeShape->shape(), actualTypeShape->shape())) {
         if (whyNot) {
-          *whyNot = "function results have distinct extents";
+          *whyNot = "function results have distinct constant extents";
         }
       } else if (!ifaceTypeShape->type().IsTkCompatibleWith(
                      actualTypeShape->type())) {