Fix infinite recursion in ScaledNumber::toInt.
authorDiego Novillo <dnovillo@google.com>
Fri, 1 May 2015 17:59:15 +0000 (17:59 +0000)
committerDiego Novillo <dnovillo@google.com>
Fri, 1 May 2015 17:59:15 +0000 (17:59 +0000)
Patch from dexonsmith. The call to toInt() was calling compareTo() which
in some cases would call back to toInt(), creating an infinite loop.

Fixed by simplifying the logic in compareTo() to avoid the co-recursion.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236326 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/ScaledNumber.h
unittests/Support/ScaledNumberTest.cpp

index dbe88f2e96fd1c584b6ac7dccdd7e3be079b84cf..0a4262b7eec5daaec9022c7b787179159f17ecee 100644 (file)
@@ -670,14 +670,7 @@ public:
     return ScaledNumbers::compare(Digits, Scale, X.Digits, X.Scale);
   }
   int compareTo(uint64_t N) const {
-    ScaledNumber Scaled = get(N);
-    int Compare = compare(Scaled);
-    if (Width == 64 || Compare != 0)
-      return Compare;
-
-    // Check for precision loss.  We know *this == RoundTrip.
-    uint64_t RoundTrip = Scaled.template toInt<uint64_t>();
-    return N == RoundTrip ? 0 : RoundTrip < N ? -1 : 1;
+    return ScaledNumbers::compare<uint64_t>(Digits, Scale, N, 0);
   }
   int compareTo(int64_t N) const { return N < 0 ? 1 : compareTo(uint64_t(N)); }
 
index 38721552ec95bb082cb94a2bf91bd25d1e7f4a86..2f38b2a40fb8f704e9228fc3df299ca54948b4a2 100644 (file)
@@ -556,4 +556,9 @@ TEST(ScaledNumberHelpersTest, arithmeticOperators) {
   EXPECT_EQ(ScaledNumber<uint64_t>(1, 4), ScaledNumber<uint64_t>(1, 3) << 1);
 }
 
+TEST(ScaledNumberHelpersTest, toIntBug) {
+  ScaledNumber<uint32_t> n(1, 0);
+  EXPECT_EQ(1u, (n * n).toInt<uint32_t>());
+}
+
 } // end namespace