[PATCH] D84352: [flang] Fix an assert when RESHAPE() is called on empty strings

Pete Steinfeld via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 22 11:35:15 PDT 2020


PeteSteinfeld created this revision.
PeteSteinfeld added reviewers: klausler, tskeith.
Herald added a reviewer: DavidTruby.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

When a constant array of empty strings goes through contant folding, the result
is something that contains no bytes.  If this array is passed to the intrinsic
function `RESHAPE()`, we were not handling things correctly.  I fixed this by
checking for an empty destination when calling the function `CopyFrom()` on an
array of strings.

I also added a test with a couple of different examples that trigger the
problem.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84352

Files:
  flang/lib/Evaluate/constant.cpp
  flang/test/Semantics/modfile25.f90


Index: flang/test/Semantics/modfile25.f90
===================================================================
--- flang/test/Semantics/modfile25.f90
+++ flang/test/Semantics/modfile25.f90
@@ -22,6 +22,9 @@
     real, intent(in) :: x(:,:)
     integer, intent(in) :: n1(3), n2(:)
     real, allocatable :: a(:,:,:)
+    ! the following fail if we don't handle empty strings
+    Character(0) :: ch1(1,2,3) = Reshape([('',n=1,1*2*3)],[1,2,3])
+    Character(0) :: ch2(3) = reshape(['','',''], [3])
     a = reshape(x,n1)
     a = reshape(x,n2(10:30:9)) ! fails if we can't figure out triplet shape
   end subroutine
Index: flang/lib/Evaluate/constant.cpp
===================================================================
--- flang/lib/Evaluate/constant.cpp
+++ flang/lib/Evaluate/constant.cpp
@@ -244,19 +244,28 @@
     std::size_t count, ConstantSubscripts &resultSubscripts,
     const std::vector<int> *dimOrder) {
   CHECK(length_ == source.length_);
-  std::size_t copied{0};
-  std::size_t elementBytes{length_ * sizeof(decltype(values_[0]))};
-  ConstantSubscripts sourceSubscripts{source.lbounds()};
-  while (copied < count) {
-    auto *dest{&values_.at(SubscriptsToOffset(resultSubscripts) * length_)};
-    const auto *src{&source.values_.at(
-        source.SubscriptsToOffset(sourceSubscripts) * length_)};
-    std::memcpy(dest, src, elementBytes);
-    copied++;
-    source.IncrementSubscripts(sourceSubscripts);
-    IncrementSubscripts(resultSubscripts, dimOrder);
+  if (length_ == 0) {
+    // It's possible that the array of strings consists of all empty strings.
+    // If so, constant folding will result in a string that's completely empty
+    // and the length_ will be zero, and there's nothing to do.
+    return count;
+  } else {
+    std::size_t copied{0};
+    std::size_t elementBytes{length_ * sizeof(decltype(values_[0]))};
+    ConstantSubscripts sourceSubscripts{source.lbounds()};
+    while (copied < count) {
+      if (copied < values_.size()) {
+        auto *dest{&values_.at(SubscriptsToOffset(resultSubscripts) * length_)};
+        const auto *src{&source.values_.at(
+            source.SubscriptsToOffset(sourceSubscripts) * length_)};
+        std::memcpy(dest, src, elementBytes);
+        copied++;
+        source.IncrementSubscripts(sourceSubscripts);
+        IncrementSubscripts(resultSubscripts, dimOrder);
+      }
+    }
+    return copied;
   }
-  return copied;
 }
 
 // Constant<SomeDerived> specialization


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D84352.279898.patch
Type: text/x-patch
Size: 2470 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200722/3d941317/attachment.bin>


More information about the llvm-commits mailing list