[flang-commits] [PATCH] D129680: [flang] Error detection/avoidance for TRANSFER with empty MOLD= type

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Wed Jul 13 16:51:09 PDT 2022


This revision was automatically updated to reflect the committed changes.
Closed by commit rGbe68a6adfba2: [flang] Error detection/avoidance for TRANSFER with empty MOLD= type (authored by klausler).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129680/new/

https://reviews.llvm.org/D129680

Files:
  flang/lib/Evaluate/shape.cpp
  flang/runtime/misc-intrinsic.cpp


Index: flang/runtime/misc-intrinsic.cpp
===================================================================
--- flang/runtime/misc-intrinsic.cpp
+++ flang/runtime/misc-intrinsic.cpp
@@ -55,16 +55,23 @@
 
 void RTNAME(Transfer)(Descriptor &result, const Descriptor &source,
     const Descriptor &mold, const char *sourceFile, int line) {
+  std::optional<std::int64_t> elements;
   if (mold.rank() > 0) {
-    std::size_t moldElementBytes{mold.ElementBytes()};
-    std::size_t elements{
-        (source.Elements() * source.ElementBytes() + moldElementBytes - 1) /
-        moldElementBytes};
-    return TransferImpl(result, source, mold, sourceFile, line,
-        static_cast<std::int64_t>(elements));
-  } else {
-    return TransferImpl(result, source, mold, sourceFile, line, {});
+    if (std::size_t sourceElementBytes{
+            source.Elements() * source.ElementBytes()}) {
+      if (std::size_t moldElementBytes{mold.ElementBytes()}) {
+        elements = static_cast<std::int64_t>(
+            (sourceElementBytes + moldElementBytes - 1) / moldElementBytes);
+      } else {
+        Terminator{sourceFile, line}.Crash("TRANSFER: zero-sized type of MOLD= "
+                                           "when SOURCE= is not zero-sized");
+      }
+    } else {
+      elements = 0;
+    }
   }
+  return TransferImpl(
+      result, source, mold, sourceFile, line, std::move(elements));
 }
 
 void RTNAME(TransferSize)(Descriptor &result, const Descriptor &source,
Index: flang/lib/Evaluate/shape.cpp
===================================================================
--- flang/lib/Evaluate/shape.cpp
+++ flang/lib/Evaluate/shape.cpp
@@ -931,19 +931,34 @@
           } else {
             // SIZE= is absent and MOLD= is array: result is vector whose
             // length is determined by sizes of types.  See 16.9.193p4 case(ii).
+            // Note that if sourceBytes is not known to be empty, we
+            // can fold only when moldElementBytes is known to not be zero;
+            // the most general case risks a division by zero otherwise.
             if (auto sourceTypeAndShape{
                     characteristics::TypeAndShape::Characterize(
                         call.arguments().at(0), *context_)}) {
-              auto sourceBytes{
-                  sourceTypeAndShape->MeasureSizeInBytes(*context_)};
-              auto moldElementBytes{
-                  moldTypeAndShape->MeasureElementSizeInBytes(*context_, true)};
-              if (sourceBytes && moldElementBytes) {
-                ExtentExpr extent{Fold(*context_,
-                    (std::move(*sourceBytes) +
-                        common::Clone(*moldElementBytes) - ExtentExpr{1}) /
-                        common::Clone(*moldElementBytes))};
-                return Shape{MaybeExtentExpr{std::move(extent)}};
+              if (auto sourceBytes{
+                      sourceTypeAndShape->MeasureSizeInBytes(*context_)}) {
+                *sourceBytes = Fold(*context_, std::move(*sourceBytes));
+                if (auto sourceBytesConst{ToInt64(*sourceBytes)}) {
+                  if (*sourceBytesConst == 0) {
+                    return Shape{ExtentExpr{0}};
+                  }
+                }
+                if (auto moldElementBytes{
+                        moldTypeAndShape->MeasureElementSizeInBytes(
+                            *context_, true)}) {
+                  *moldElementBytes =
+                      Fold(*context_, std::move(*moldElementBytes));
+                  auto moldElementBytesConst{ToInt64(*moldElementBytes)};
+                  if (moldElementBytesConst && *moldElementBytesConst != 0) {
+                    ExtentExpr extent{Fold(*context_,
+                        (std::move(*sourceBytes) +
+                            common::Clone(*moldElementBytes) - ExtentExpr{1}) /
+                            common::Clone(*moldElementBytes))};
+                    return Shape{MaybeExtentExpr{std::move(extent)}};
+                  }
+                }
               }
             }
           }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D129680.444458.patch
Type: text/x-patch
Size: 4057 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20220713/68036061/attachment.bin>


More information about the flang-commits mailing list