[libc-commits] [libc] 6472421 - [libc] Fix mixed-sign comparison warnings and an out-of-bound access in high_precision_decimal.h

Tue Ly via libc-commits libc-commits at lists.llvm.org
Mon Feb 7 13:23:22 PST 2022


Author: Tue Ly
Date: 2022-02-07T16:23:09-05:00
New Revision: 6472421840885a0129f42146bdeb5d416652b9f4

URL: https://github.com/llvm/llvm-project/commit/6472421840885a0129f42146bdeb5d416652b9f4
DIFF: https://github.com/llvm/llvm-project/commit/6472421840885a0129f42146bdeb5d416652b9f4.diff

LOG: [libc] Fix mixed-sign comparison warnings and an out-of-bound access in high_precision_decimal.h

Fix mixed-sign comparison warnings and an out-of-bound access in high_precision_decimal.h

Reviewed By: michaelrj

Differential Revision: https://reviews.llvm.org/D119156

Added: 
    

Modified: 
    libc/src/__support/high_precision_decimal.h
    libc/test/src/__support/high_precision_decimal_test.cpp
    libc/test/src/__support/str_to_float_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/high_precision_decimal.h b/libc/src/__support/high_precision_decimal.h
index 1b941da212aa1..16d0ef8cc9038 100644
--- a/libc/src/__support/high_precision_decimal.h
+++ b/libc/src/__support/high_precision_decimal.h
@@ -112,13 +112,14 @@ class HighPrecisionDecimal {
 
 private:
   bool should_round_up(int32_t roundToDigit) {
-    if (roundToDigit < 0 || roundToDigit >= this->num_digits) {
+    if (roundToDigit < 0 ||
+        static_cast<uint32_t>(roundToDigit) >= this->num_digits) {
       return false;
     }
 
     // If we're right in the middle and there are no extra digits
     if (this->digits[roundToDigit] == 5 &&
-        roundToDigit + 1 == this->num_digits) {
+        static_cast<uint32_t>(roundToDigit + 1) == this->num_digits) {
 
       // Round up if we've truncated (since that means the result is slightly
       // higher than what's represented.)
@@ -127,6 +128,9 @@ class HighPrecisionDecimal {
       }
 
       // If this exactly halfway, round to even.
+      if (roundToDigit == 0)
+        // When the input is ".5".
+        return false;
       return this->digits[roundToDigit - 1] % 2 != 0;
     }
     // If there are digits after roundToDigit, they must be non-zero since we

diff  --git a/libc/test/src/__support/high_precision_decimal_test.cpp b/libc/test/src/__support/high_precision_decimal_test.cpp
index 7b04d78501d5e..1761dae0fcf93 100644
--- a/libc/test/src/__support/high_precision_decimal_test.cpp
+++ b/libc/test/src/__support/high_precision_decimal_test.cpp
@@ -36,6 +36,17 @@ TEST(LlvmLibcHighPrecisionDecimalTest, BasicShift) {
   EXPECT_EQ(hpd.get_decimal_point(), 1);
 }
 
+TEST(LlvmLibcHighPrecisionDecimalTest, ShouldRoundup) {
+  __llvm_libc::internal::HighPrecisionDecimal hpd =
+      __llvm_libc::internal::HighPrecisionDecimal(".5");
+  uint8_t *digits = hpd.get_digits();
+
+  EXPECT_EQ(digits[0], uint8_t(5));
+  EXPECT_EQ(hpd.get_num_digits(), 1u);
+  EXPECT_EQ(hpd.get_decimal_point(), 0);
+  EXPECT_EQ(hpd.round_to_integer_type<int>(), 0);
+}
+
 TEST(LlvmLibcHighPrecisionDecimalTest, SmallShift) {
   __llvm_libc::internal::HighPrecisionDecimal hpd =
       __llvm_libc::internal::HighPrecisionDecimal("1.2345");

diff  --git a/libc/test/src/__support/str_to_float_test.cpp b/libc/test/src/__support/str_to_float_test.cpp
index e75434621157e..fa2efda422019 100644
--- a/libc/test/src/__support/str_to_float_test.cpp
+++ b/libc/test/src/__support/str_to_float_test.cpp
@@ -232,6 +232,11 @@ TEST_F(LlvmLibcStrToFloatTest, SimpleDecimalConversion32SpecificFailures) {
   simple_decimal_conversion_test<float>(
       "1.4012984643248170709237295832899161312802619418765e-45", 0x1, 0,
       ERANGE);
+  simple_decimal_conversion_test<float>(
+      "7."
+      "006492321624085354618647916449580656401309709382578858785341419448955413"
+      "42930300743319094181060791015625e-46",
+      0x0, 0, ERANGE);
 }
 
 TEST(LlvmLibcStrToFloatTest, SimpleDecimalConversionExtraTypes) {


        


More information about the libc-commits mailing list