[flang-commits] [PATCH] D89435: [flang][msvc] Avoid a reinterpret_cast
Peter Klausler via Phabricator via flang-commits
flang-commits at lists.llvm.org
Wed Oct 14 16:37:08 PDT 2020
klausler created this revision.
klausler added a reviewer: Meinersbur.
klausler added a project: Flang.
Herald added subscribers: llvm-commits, jdoerfert.
Herald added a project: LLVM.
klausler requested review of this revision.
The call to the binary->decimal formatter in real.cpp was cheating
by using a reinterpret_cast<> to extract its binary value.
Use a more principled and portable approach by extending the
API of evaluate::Integer<> to include ToUInt<>()/ToSInt<>()
member function templates that do the "right" thing. Retain
ToUInt64()/ToSInt64() for compatibility.
Proposed as an alternative to https://reviews.llvm.org/D88798.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D89435
Files:
flang/include/flang/Evaluate/integer.h
flang/lib/Evaluate/real.cpp
Index: flang/lib/Evaluate/real.cpp
===================================================================
--- flang/lib/Evaluate/real.cpp
+++ flang/lib/Evaluate/real.cpp
@@ -496,14 +496,15 @@
}
} else {
using B = decimal::BinaryFloatingPointNumber<P>;
- const auto *value{reinterpret_cast<const B *>(this)};
- char buffer[24000]; // accommodate real*16
+ B value{word_.template ToUInt<typename B::RawType>()};
+ char buffer[common::MaxDecimalConversionDigits(P) +
+ EXTRA_DECIMAL_CONVERSION_SPACE];
decimal::DecimalConversionFlags flags{}; // default: exact representation
if (minimal) {
flags = decimal::Minimize;
}
auto result{decimal::ConvertToDecimal<P>(buffer, sizeof buffer, flags,
- static_cast<int>(sizeof buffer), decimal::RoundNearest, *value)};
+ static_cast<int>(sizeof buffer), decimal::RoundNearest, value)};
const char *p{result.str};
if (DEREF(p) == '-' || *p == '+') {
o << *p++;
Index: flang/include/flang/Evaluate/integer.h
===================================================================
--- flang/include/flang/Evaluate/integer.h
+++ flang/include/flang/Evaluate/integer.h
@@ -462,21 +462,30 @@
return CompareUnsigned(y);
}
- constexpr std::uint64_t ToUInt64() const {
- std::uint64_t n{LEPart(0)};
- int filled{partBits};
- for (int j{1}; filled < 64 && j < parts; ++j, filled += partBits) {
- n |= std::uint64_t{LEPart(j)} << filled;
+ template <typename UINT = std::uint64_t> constexpr UINT ToUInt() const {
+ UINT n{LEPart(0)};
+ std::size_t filled{partBits};
+ constexpr std::size_t maxBits{CHAR_BIT * sizeof n};
+ for (int j{1}; filled < maxBits && j < parts; ++j, filled += partBits) {
+ n |= UINT{LEPart(j)} << filled;
}
return n;
}
- constexpr std::int64_t ToInt64() const {
- std::int64_t signExtended = ToUInt64();
- if constexpr (bits < 64) {
- signExtended |= -(signExtended >> (bits - 1)) << bits;
+ template <typename SINT = std::int64_t, typename UINT = std::uint64_t>
+ constexpr SINT ToSInt() const {
+ SINT n = ToUInt<UINT>();
+ constexpr std::size_t maxBits{CHAR_BIT * sizeof n};
+ if constexpr (bits < maxBits) {
+ n |= -(n >> (bits - 1)) << bits;
}
- return signExtended;
+ return n;
+ }
+
+ constexpr std::uint64_t ToUInt64() const { return ToUInt<std::uint64_t>(); }
+
+ constexpr std::int64_t ToInt64() const {
+ return ToSInt<std::int64_t, std::uint64_t>();
}
// Ones'-complement (i.e., C's ~)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D89435.298261.patch
Type: text/x-patch
Size: 2542 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20201014/5e5d99f9/attachment.bin>
More information about the flang-commits
mailing list