diff --git a/llvm/lib/Support/APSInt.cpp b/llvm/lib/Support/APSInt.cpp --- a/llvm/lib/Support/APSInt.cpp +++ b/llvm/lib/Support/APSInt.cpp @@ -26,14 +26,14 @@ APInt Tmp(NumBits, Str, /*radix=*/10); if (Str[0] == '-') { unsigned MinBits = Tmp.getMinSignedBits(); - if (MinBits > 0 && MinBits < NumBits) - Tmp = Tmp.trunc(MinBits); + if (MinBits < NumBits) + Tmp = Tmp.trunc(std::max(1, MinBits)); *this = APSInt(Tmp, /*isUnsigned=*/false); return; } unsigned ActiveBits = Tmp.getActiveBits(); - if (ActiveBits > 0 && ActiveBits < NumBits) - Tmp = Tmp.trunc(ActiveBits); + if (ActiveBits < NumBits) + Tmp = Tmp.trunc(std::max(1, ActiveBits)); *this = APSInt(Tmp, /*isUnsigned=*/true); } diff --git a/llvm/unittests/ADT/APSIntTest.cpp b/llvm/unittests/ADT/APSIntTest.cpp --- a/llvm/unittests/ADT/APSIntTest.cpp +++ b/llvm/unittests/ADT/APSIntTest.cpp @@ -150,6 +150,29 @@ EXPECT_EQ(APSInt("-1234").getExtValue(), -1234); } +TEST(APSIntTest, FromStringBitWidth) { + EXPECT_EQ(APSInt("0").getBitWidth(), 1U); + EXPECT_EQ(APSInt("000").getBitWidth(), 1U); + EXPECT_EQ(APSInt("1").getBitWidth(), 1U); + EXPECT_EQ(APSInt("2").getBitWidth(), 2U); + EXPECT_EQ(APSInt("3").getBitWidth(), 2U); + EXPECT_EQ(APSInt("003").getBitWidth(), 2U); + EXPECT_EQ(APSInt("15").getBitWidth(), 4U); + EXPECT_EQ(APSInt("16").getBitWidth(), 5U); + EXPECT_EQ(APSInt("17").getBitWidth(), 5U); + + EXPECT_EQ(APSInt("-0").getBitWidth(), 1U); + EXPECT_EQ(APSInt("-000").getBitWidth(), 1U); + EXPECT_EQ(APSInt("-1").getBitWidth(), 1U); + EXPECT_EQ(APSInt("-2").getBitWidth(), 2U); + EXPECT_EQ(APSInt("-3").getBitWidth(), 3U); + EXPECT_EQ(APSInt("-003").getBitWidth(), 3U); + EXPECT_EQ(APSInt("-5").getBitWidth(), 4U); + EXPECT_EQ(APSInt("-15").getBitWidth(), 5U); + EXPECT_EQ(APSInt("-16").getBitWidth(), 5U); + EXPECT_EQ(APSInt("-17").getBitWidth(), 6U); +} + #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) TEST(APSIntTest, StringDeath) {