Index: llvm/lib/Support/StringRef.cpp =================================================================== --- llvm/lib/Support/StringRef.cpp +++ llvm/lib/Support/StringRef.cpp @@ -404,7 +404,7 @@ Str = Str.substr(2); return 16; } - + if (Str.startswith("0b") || Str.startswith("0B")) { Str = Str.substr(2); return 2; @@ -428,7 +428,18 @@ // Autosense radix if not specified. if (Radix == 0) Radix = GetAutoSenseRadix(Str); - + else { + // Even if the radix is specified, there might still be a radix prefix. + if (Radix == 2 && Str.startswith_lower("0b")) + Str = Str.drop_front(2); + else if (Radix == 8) { + if (Str.startswith("0o")) + Str = Str.drop_front(2); + else if (Str[0] == '0' && Str.size() > 1 && ascii_isdigit(Str[1])) + Str = Str.drop_front(); + } else if (Radix == 16 && Str.startswith_lower("0x")) + Str = Str.drop_front(2); + } // Empty strings (after the radix autosense) are invalid. if (Str.empty()) return true; Index: llvm/unittests/ADT/StringRefTest.cpp =================================================================== --- llvm/unittests/ADT/StringRefTest.cpp +++ llvm/unittests/ADT/StringRefTest.cpp @@ -549,47 +549,45 @@ struct UnsignedPair { const char *Str; + unsigned Radix; uint64_t Expected; -} Unsigned[] = - { {"0", 0} - , {"255", 255} - , {"256", 256} - , {"65535", 65535} - , {"65536", 65536} - , {"4294967295", 4294967295ULL} - , {"4294967296", 4294967296ULL} - , {"18446744073709551615", 18446744073709551615ULL} - , {"042", 34} - , {"0x42", 66} - , {"0b101010", 42} - }; +} Unsigned[] = {{"0", 10, 0}, + {"255", 10, 255}, + {"256", 10, 256}, + {"65535", 10, 65535}, + {"65536", 10, 65536}, + {"4294967295", 10, 4294967295ULL}, + {"4294967296", 10, 4294967296ULL}, + {"18446744073709551615", 10, 18446744073709551615ULL}, + {"042", 8, 34}, + {"0x42", 16, 66}, + {"0b101010", 2, 42}}; struct SignedPair { const char *Str; + unsigned Radix; int64_t Expected; -} Signed[] = - { {"0", 0} - , {"-0", 0} - , {"127", 127} - , {"128", 128} - , {"-128", -128} - , {"-129", -129} - , {"32767", 32767} - , {"32768", 32768} - , {"-32768", -32768} - , {"-32769", -32769} - , {"2147483647", 2147483647LL} - , {"2147483648", 2147483648LL} - , {"-2147483648", -2147483648LL} - , {"-2147483649", -2147483649LL} - , {"-9223372036854775808", -(9223372036854775807LL) - 1} - , {"042", 34} - , {"0x42", 66} - , {"0b101010", 42} - , {"-042", -34} - , {"-0x42", -66} - , {"-0b101010", -42} - }; +} Signed[] = {{"0", 10, 0}, + {"-0", 10, 0}, + {"127", 10, 127}, + {"128", 10, 128}, + {"-128", 10, -128}, + {"-129", 10, -129}, + {"32767", 10, 32767}, + {"32768", 10, 32768}, + {"-32768", 10, -32768}, + {"-32769", 10, -32769}, + {"2147483647", 10, 2147483647LL}, + {"2147483648", 10, 2147483648LL}, + {"-2147483648", 10, -2147483648LL}, + {"-2147483649", 10, -2147483649LL}, + {"-9223372036854775808", 10, -(9223372036854775807LL) - 1}, + {"042", 8, 34}, + {"0x42", 16, 66}, + {"0b101010", 2, 42}, + {"-042", 8, -34}, + {"-0x42", 16, -66}, + {"-0b101010", 2, -42}}; TEST(StringRefTest, getAsInteger) { uint8_t U8; @@ -598,33 +596,35 @@ uint64_t U64; for (size_t i = 0; i < array_lengthof(Unsigned); ++i) { - bool U8Success = StringRef(Unsigned[i].Str).getAsInteger(0, U8); - if (static_cast(Unsigned[i].Expected) == Unsigned[i].Expected) { - ASSERT_FALSE(U8Success); - EXPECT_EQ(U8, Unsigned[i].Expected); - } else { - ASSERT_TRUE(U8Success); - } - bool U16Success = StringRef(Unsigned[i].Str).getAsInteger(0, U16); - if (static_cast(Unsigned[i].Expected) == Unsigned[i].Expected) { - ASSERT_FALSE(U16Success); - EXPECT_EQ(U16, Unsigned[i].Expected); - } else { - ASSERT_TRUE(U16Success); - } - bool U32Success = StringRef(Unsigned[i].Str).getAsInteger(0, U32); - if (static_cast(Unsigned[i].Expected) == Unsigned[i].Expected) { - ASSERT_FALSE(U32Success); - EXPECT_EQ(U32, Unsigned[i].Expected); - } else { - ASSERT_TRUE(U32Success); - } - bool U64Success = StringRef(Unsigned[i].Str).getAsInteger(0, U64); - if (static_cast(Unsigned[i].Expected) == Unsigned[i].Expected) { - ASSERT_FALSE(U64Success); - EXPECT_EQ(U64, Unsigned[i].Expected); - } else { - ASSERT_TRUE(U64Success); + for (unsigned Radix : {0u, Unsigned[i].Radix}) { + bool U8Success = StringRef(Unsigned[i].Str).getAsInteger(Radix, U8); + if (static_cast(Unsigned[i].Expected) == Unsigned[i].Expected) { + ASSERT_FALSE(U8Success); + EXPECT_EQ(U8, Unsigned[i].Expected); + } else { + ASSERT_TRUE(U8Success); + } + bool U16Success = StringRef(Unsigned[i].Str).getAsInteger(Radix, U16); + if (static_cast(Unsigned[i].Expected) == Unsigned[i].Expected) { + ASSERT_FALSE(U16Success); + EXPECT_EQ(U16, Unsigned[i].Expected); + } else { + ASSERT_TRUE(U16Success); + } + bool U32Success = StringRef(Unsigned[i].Str).getAsInteger(Radix, U32); + if (static_cast(Unsigned[i].Expected) == Unsigned[i].Expected) { + ASSERT_FALSE(U32Success); + EXPECT_EQ(U32, Unsigned[i].Expected); + } else { + ASSERT_TRUE(U32Success); + } + bool U64Success = StringRef(Unsigned[i].Str).getAsInteger(Radix, U64); + if (static_cast(Unsigned[i].Expected) == Unsigned[i].Expected) { + ASSERT_FALSE(U64Success); + EXPECT_EQ(U64, Unsigned[i].Expected); + } else { + ASSERT_TRUE(U64Success); + } } } @@ -634,38 +634,39 @@ int64_t S64; for (size_t i = 0; i < array_lengthof(Signed); ++i) { - bool S8Success = StringRef(Signed[i].Str).getAsInteger(0, S8); - if (static_cast(Signed[i].Expected) == Signed[i].Expected) { - ASSERT_FALSE(S8Success); - EXPECT_EQ(S8, Signed[i].Expected); - } else { - ASSERT_TRUE(S8Success); - } - bool S16Success = StringRef(Signed[i].Str).getAsInteger(0, S16); - if (static_cast(Signed[i].Expected) == Signed[i].Expected) { - ASSERT_FALSE(S16Success); - EXPECT_EQ(S16, Signed[i].Expected); - } else { - ASSERT_TRUE(S16Success); - } - bool S32Success = StringRef(Signed[i].Str).getAsInteger(0, S32); - if (static_cast(Signed[i].Expected) == Signed[i].Expected) { - ASSERT_FALSE(S32Success); - EXPECT_EQ(S32, Signed[i].Expected); - } else { - ASSERT_TRUE(S32Success); - } - bool S64Success = StringRef(Signed[i].Str).getAsInteger(0, S64); - if (static_cast(Signed[i].Expected) == Signed[i].Expected) { - ASSERT_FALSE(S64Success); - EXPECT_EQ(S64, Signed[i].Expected); - } else { - ASSERT_TRUE(S64Success); + for (unsigned Radix : {0u, Signed[i].Radix}) { + bool S8Success = StringRef(Signed[i].Str).getAsInteger(Radix, S8); + if (static_cast(Signed[i].Expected) == Signed[i].Expected) { + ASSERT_FALSE(S8Success); + EXPECT_EQ(S8, Signed[i].Expected); + } else { + ASSERT_TRUE(S8Success); + } + bool S16Success = StringRef(Signed[i].Str).getAsInteger(Radix, S16); + if (static_cast(Signed[i].Expected) == Signed[i].Expected) { + ASSERT_FALSE(S16Success); + EXPECT_EQ(S16, Signed[i].Expected); + } else { + ASSERT_TRUE(S16Success); + } + bool S32Success = StringRef(Signed[i].Str).getAsInteger(Radix, S32); + if (static_cast(Signed[i].Expected) == Signed[i].Expected) { + ASSERT_FALSE(S32Success); + EXPECT_EQ(S32, Signed[i].Expected); + } else { + ASSERT_TRUE(S32Success); + } + bool S64Success = StringRef(Signed[i].Str).getAsInteger(Radix, S64); + if (static_cast(Signed[i].Expected) == Signed[i].Expected) { + ASSERT_FALSE(S64Success); + EXPECT_EQ(S64, Signed[i].Expected); + } else { + ASSERT_TRUE(S64Success); + } } } } - static const char* BadStrings[] = { "" // empty string , "18446744073709551617" // value just over max