Skip to content

Commit 127eb39

Browse files
authored
[LLVM][PDB] Use IsUnsigned flag for APInt correctly (llvm#131598)
This patch fixes an assertion that occurs in `APInt`. The assertion can be reproduced with LLDB test `python_api/thread/TestThreadAPI.py` (it fails).
1 parent 695a007 commit 127eb39

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

llvm/include/llvm/DebugInfo/PDB/PDBTypes.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,9 @@ struct Variant {
510510

511511
#define VARIANT_APSINT(Enum, NumBits, IsUnsigned) \
512512
case PDB_VariantType::Enum: \
513-
return APSInt(APInt(NumBits, Value.Enum), IsUnsigned);
513+
return APSInt( \
514+
APInt(NumBits, static_cast<uint64_t>(Value.Enum), !IsUnsigned), \
515+
IsUnsigned);
514516

515517
APSInt toAPSInt() const {
516518
switch (Type) {

llvm/unittests/DebugInfo/PDB/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ add_llvm_unittest_with_input_files(DebugInfoPDBTests
1010
NativeSymbolReuseTest.cpp
1111
StringTableBuilderTest.cpp
1212
PDBApiTest.cpp
13+
PDBVariantTest.cpp
1314
)
1415

1516
target_link_libraries(DebugInfoPDBTests PRIVATE LLVMTestingSupport)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===- llvm/unittest/DebugInfo/PDB/PDBVariantTest.cpp ---------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "gtest/gtest.h"
10+
11+
#include "llvm/DebugInfo/PDB/PDBTypes.h"
12+
13+
using namespace llvm;
14+
using namespace llvm::pdb;
15+
16+
namespace {
17+
18+
template <typename T> class PDBVariantIntegerTest : public testing::Test {
19+
public:
20+
std::vector<T> getTestIntegers() {
21+
if constexpr (std::is_same_v<T, bool>) {
22+
return {true, false};
23+
} else {
24+
std::vector<T> Integers{0, 1, 32, std::numeric_limits<T>::min(),
25+
std::numeric_limits<T>::max()};
26+
if constexpr (std::is_signed_v<T>) {
27+
Integers.emplace_back(-1);
28+
Integers.emplace_back(-65);
29+
}
30+
return Integers;
31+
}
32+
}
33+
};
34+
35+
using TestTypes = testing::Types<bool, int8_t, uint8_t, int16_t, uint16_t,
36+
int32_t, uint32_t, int64_t, uint64_t>;
37+
38+
} // namespace
39+
40+
TYPED_TEST_SUITE(PDBVariantIntegerTest, TestTypes);
41+
42+
TYPED_TEST(PDBVariantIntegerTest, ToAPSInt) {
43+
for (TypeParam IntegerValue : this->getTestIntegers()) {
44+
const Variant VariantValue(IntegerValue);
45+
46+
const APSInt APSIntValue = VariantValue.toAPSInt();
47+
EXPECT_EQ(APSIntValue.isSigned(), std::is_signed_v<TypeParam>)
48+
<< "Unexpected 'isSigned()' result for '" << IntegerValue << "'";
49+
bool IsNegative = false;
50+
if constexpr (!std::is_same_v<TypeParam, bool>) {
51+
IsNegative = IntegerValue < 0;
52+
}
53+
EXPECT_EQ(APSIntValue.isNegative(), IsNegative)
54+
<< "Unexpected 'isNegative()' result for '" << IntegerValue << "'";
55+
56+
SmallString<20> String;
57+
APSIntValue.toString(String);
58+
EXPECT_EQ(String.str().str(), std::to_string(IntegerValue));
59+
}
60+
}

0 commit comments

Comments
 (0)