[flang-commits] [flang] 60b1fcb - [flang] Correct folding of TRANSFER(integer, character array)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Fri Jul 22 17:28:20 PDT 2022
Author: Peter Klausler
Date: 2022-07-22T17:28:08-07:00
New Revision: 60b1fcb1a550b7a7ed0324f122efcd8da1c77eb2
URL: https://github.com/llvm/llvm-project/commit/60b1fcb1a550b7a7ed0324f122efcd8da1c77eb2
DIFF: https://github.com/llvm/llvm-project/commit/60b1fcb1a550b7a7ed0324f122efcd8da1c77eb2.diff
LOG: [flang] Correct folding of TRANSFER(integer, character array)
The code that copies data from a constant source array into a character
array constant result was failing to copy its last element if it was
only partially defined due to misalignment.
Differential Revision: https://reviews.llvm.org/D130376
Added:
Modified:
flang/lib/Evaluate/initial-image.cpp
flang/test/Evaluate/fold-transfer.f90
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/initial-image.cpp b/flang/lib/Evaluate/initial-image.cpp
index 0daffea66d87b..cf70b6e888706 100644
--- a/flang/lib/Evaluate/initial-image.cpp
+++ b/flang/lib/Evaluate/initial-image.cpp
@@ -135,12 +135,22 @@ class AsConstantHelper {
for (std::size_t j{0}; j < elements; ++j) {
using Char = typename Scalar::value_type;
auto at{static_cast<std::size_t>(offset_ + j * stride)};
- if (at + length > image_.data_.size()) {
+ auto chunk{length};
+ if (at + chunk > image_.data_.size()) {
CHECK(padWithZero_);
- break;
+ if (at >= image_.data_.size()) {
+ chunk = 0;
+ } else {
+ chunk = image_.data_.size() - at;
+ }
+ }
+ if (chunk > 0) {
+ const Char *data{reinterpret_cast<const Char *>(&image_.data_[at])};
+ typedValue[j].assign(data, chunk);
+ }
+ if (chunk < length && padWithZero_) {
+ typedValue[j].append(length - chunk, Char{});
}
- const Char *data{reinterpret_cast<const Char *>(&image_.data_[at])};
- typedValue[j].assign(data, length);
}
return AsGenericExpr(
Const{length, std::move(typedValue), std::move(extents_)});
@@ -153,12 +163,15 @@ class AsConstantHelper {
if (at + chunk > image_.data_.size()) {
CHECK(padWithZero_);
if (at >= image_.data_.size()) {
- break;
+ chunk = 0;
+ } else {
+ chunk = image_.data_.size() - at;
}
- chunk = image_.data_.size() - at;
}
// TODO endianness
- std::memcpy(&typedValue[j], &image_.data_[at], chunk);
+ if (chunk > 0) {
+ std::memcpy(&typedValue[j], &image_.data_[at], chunk);
+ }
}
return AsGenericExpr(Const{std::move(typedValue), std::move(extents_)});
}
diff --git a/flang/test/Evaluate/fold-transfer.f90 b/flang/test/Evaluate/fold-transfer.f90
index ef5a52f83e0a1..833c828a62966 100644
--- a/flang/test/Evaluate/fold-transfer.f90
+++ b/flang/test/Evaluate/fold-transfer.f90
@@ -34,4 +34,9 @@ module m
logical, parameter :: test_c2i_v_2 = all(jc3 == [int(z'61626364'), int(z'65666768')]) .or. all(jc3 == [int(z'64636261'), int(z'68676665')])
integer, parameter :: jc4(*) = transfer(["abcd", "efgh"], 0, 1)
logical, parameter :: test_c2i_vs_1 = all(jc4 == [int(z'61626364')]) .or. all(jc4 == [int(z'64636261')])
+
+ integer, parameter :: le1 = int(z'64636261', 4), be1 = int(z'65666768', 4)
+ character*5, parameter :: le1c(*) = transfer(le1, [character(5)::])
+ character*5, parameter :: be1c(*) = transfer(be1, [character(5)::])
+ logical, parameter :: test_i2c_s = all(le1c == ["abcd"//char(0)]) .or. all(be1c == ["efgh"//char(0)])
end module
More information about the flang-commits
mailing list