diff --git a/flang/include/flang/Evaluate/integer.h b/flang/include/flang/Evaluate/integer.h --- a/flang/include/flang/Evaluate/integer.h +++ b/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 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 + constexpr SINT ToSInt() const { + SINT n = ToUInt(); + 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(); } + + constexpr std::int64_t ToInt64() const { + return ToSInt(); } // Ones'-complement (i.e., C's ~) diff --git a/flang/lib/Evaluate/real.cpp b/flang/lib/Evaluate/real.cpp --- a/flang/lib/Evaluate/real.cpp +++ b/flang/lib/Evaluate/real.cpp @@ -496,14 +496,15 @@ } } else { using B = decimal::BinaryFloatingPointNumber

; - const auto *value{reinterpret_cast(this)}; - char buffer[24000]; // accommodate real*16 + B value{word_.template ToUInt()}; + char buffer[common::MaxDecimalConversionDigits(P) + + EXTRA_DECIMAL_CONVERSION_SPACE]; decimal::DecimalConversionFlags flags{}; // default: exact representation if (minimal) { flags = decimal::Minimize; } auto result{decimal::ConvertToDecimal

(buffer, sizeof buffer, flags, - static_cast(sizeof buffer), decimal::RoundNearest, *value)}; + static_cast(sizeof buffer), decimal::RoundNearest, value)}; const char *p{result.str}; if (DEREF(p) == '-' || *p == '+') { o << *p++;