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.

llvm-svn: 236326

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

index dbe88f2..0a4262b 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 3872155..2f38b2a 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