[flang-commits] [flang] [flang] Check for overflows in RESHAPE folding (PR #68342)

Leandro Lupori via flang-commits flang-commits at lists.llvm.org
Thu Oct 5 12:07:21 PDT 2023


https://github.com/luporl created https://github.com/llvm/llvm-project/pull/68342

None

>From daa8de4653bc9e4fd7f8b5827b3b0e0cc3be9213 Mon Sep 17 00:00:00 2001
From: Leandro Lupori <leandro.lupori at linaro.org>
Date: Wed, 4 Oct 2023 18:15:38 +0000
Subject: [PATCH] [flang] Check for overflows in RESHAPE folding

---
 flang/include/flang/Evaluate/constant.h  |  1 +
 flang/lib/Evaluate/constant.cpp          | 14 ++++++++++++++
 flang/lib/Evaluate/fold-implementation.h |  3 +++
 flang/test/Semantics/reshape.f90         |  5 +++++
 4 files changed, 23 insertions(+)

diff --git a/flang/include/flang/Evaluate/constant.h b/flang/include/flang/Evaluate/constant.h
index 04474e2f49a0f88..c5e08d38f793234 100644
--- a/flang/include/flang/Evaluate/constant.h
+++ b/flang/include/flang/Evaluate/constant.h
@@ -47,6 +47,7 @@ inline int GetRank(const ConstantSubscripts &s) {
 }
 
 std::size_t TotalElementCount(const ConstantSubscripts &);
+bool TotalElementCountOverflows(const ConstantSubscripts &);
 
 // Validate dimension re-ordering like ORDER in RESHAPE.
 // On success, return a vector that can be used as dimOrder in
diff --git a/flang/lib/Evaluate/constant.cpp b/flang/lib/Evaluate/constant.cpp
index 084836b4ec36773..76403364ce503e3 100644
--- a/flang/lib/Evaluate/constant.cpp
+++ b/flang/lib/Evaluate/constant.cpp
@@ -84,6 +84,20 @@ std::size_t TotalElementCount(const ConstantSubscripts &shape) {
   return static_cast<std::size_t>(GetSize(shape));
 }
 
+bool TotalElementCountOverflows(const ConstantSubscripts &shape) {
+  uint64_t size{1};
+  for (auto dim : shape) {
+    CHECK(dim >= 0);
+    uint64_t osize{size};
+    size = osize * dim;
+    if (size > std::numeric_limits<decltype(dim)>::max() ||
+        (dim != 0 && size / dim != osize)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 bool ConstantBounds::IncrementSubscripts(
     ConstantSubscripts &indices, const std::vector<int> *dimOrder) const {
   int rank{GetRank(shape_)};
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index 2a40018cd5a3865..0748a27268aee26 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -878,6 +878,9 @@ template <typename T> Expr<T> Folder<T>::RESHAPE(FunctionRef<T> &&funcRef) {
   } else if (HasNegativeExtent(shape.value())) {
     context_.messages().Say(
         "'shape=' argument must not have a negative extent"_err_en_US);
+  } else if (TotalElementCountOverflows(shape.value())) {
+    context_.messages().Say(
+        "'shape=' argument has too many elements"_err_en_US);
   } else {
     int rank{GetRank(shape.value())};
     std::size_t resultElements{TotalElementCount(shape.value())};
diff --git a/flang/test/Semantics/reshape.f90 b/flang/test/Semantics/reshape.f90
index 2e9b5adf3ff0e50..4f9be6510e5dcd4 100644
--- a/flang/test/Semantics/reshape.f90
+++ b/flang/test/Semantics/reshape.f90
@@ -44,6 +44,11 @@ program reshaper
   type(dType), parameter :: array19(*) = [dType::dType(field=[1,2])]
   logical, parameter :: lVar = all(array19(:)%field(1) == [2])
 
+  integer(8), parameter :: I64_MAX = INT(z'7fffffffffffffff', kind=8)
+  integer(8), parameter :: huge_shape(2) = [I64_MAX, I64_MAX]
+  !ERROR: 'shape=' argument has too many elements
+  integer :: array21(I64_MAX, I64_MAX) = RESHAPE([1, 2, 3], huge_shape)
+
   !ERROR: Size of 'shape=' argument must not be greater than 15
   CALL ext_sub(RESHAPE([(n, n=1,20)], &
     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]))



More information about the flang-commits mailing list