diff options
| author | Bryan Chan <bryan.chan@ca.ibm.com> | 2016-05-19 13:51:20 +0000 |
|---|---|---|
| committer | Bryan Chan <bryan.chan@ca.ibm.com> | 2016-05-19 13:51:20 +0000 |
| commit | 01319e93abe3a4d3e722de4e849762ea54d12d70 (patch) | |
| tree | 1e6681400f5fead23cfc4270bc2b994a055a889d | |
| parent | cda1bd50488d0f0ded3e708c6c669cb259050fb3 (diff) | |
| download | bcm5719-llvm-01319e93abe3a4d3e722de4e849762ea54d12d70.tar.gz bcm5719-llvm-01319e93abe3a4d3e722de4e849762ea54d12d70.zip | |
Avoid an assertion failure when a bit field is extracted from a value of the same size.
Summary: One of the cases handled by ValueObjectChild::UpdateValue() uses the entire width of the parent's scalar value as the size of the child, and extracts the child by calling Scalar::ExtractBitfield(). This seems valid but APInt::trunc(), APInt::sext() and APInt::zext() assert that the bit field must not have the same size as the parent scalar. Replacing those calls with sextOrTrunc(), zextOrTrunc(), sextOrSelf() and zextOrSelf() fixes the assertion failures.
Reviewers: uweigand, labath
Subscribers: labath, lldb-commits
Differential Revision: http://reviews.llvm.org/D20355
llvm-svn: 270062
| -rw-r--r-- | lldb/source/Core/Scalar.cpp | 4 | ||||
| -rw-r--r-- | lldb/unittests/Core/ScalarTest.cpp | 24 |
2 files changed, 26 insertions, 2 deletions
diff --git a/lldb/source/Core/Scalar.cpp b/lldb/source/Core/Scalar.cpp index 2462a972e6b..d3e9a756504 100644 --- a/lldb/source/Core/Scalar.cpp +++ b/lldb/source/Core/Scalar.cpp @@ -2788,7 +2788,7 @@ Scalar::ExtractBitfield (uint32_t bit_size, case Scalar::e_slonglong: case Scalar::e_sint128: case Scalar::e_sint256: - m_integer = m_integer.ashr(bit_offset).trunc(bit_size).sext(8 * GetByteSize()); + m_integer = m_integer.ashr(bit_offset).sextOrTrunc(bit_size).sextOrSelf(8 * GetByteSize()); return true; case Scalar::e_uint: @@ -2796,7 +2796,7 @@ Scalar::ExtractBitfield (uint32_t bit_size, case Scalar::e_ulonglong: case Scalar::e_uint128: case Scalar::e_uint256: - m_integer = m_integer.lshr(bit_offset).trunc(bit_size).zext(8 * GetByteSize()); + m_integer = m_integer.lshr(bit_offset).zextOrTrunc(bit_size).zextOrSelf(8 * GetByteSize()); return true; } return false; diff --git a/lldb/unittests/Core/ScalarTest.cpp b/lldb/unittests/Core/ScalarTest.cpp index 2a5643fee1a..bf85f8e9623 100644 --- a/lldb/unittests/Core/ScalarTest.cpp +++ b/lldb/unittests/Core/ScalarTest.cpp @@ -79,3 +79,27 @@ TEST(ScalarTest, CastOperations) ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong()); } +TEST(ScalarTest, ExtractBitfield) +{ + uint32_t len = sizeof(long long) * 8; + + long long a1 = 0xf1f2f3f4f5f6f7f8LL; + long long b1 = 0xff1f2f3f4f5f6f7fLL; + Scalar s_scalar(a1); + ASSERT_TRUE(s_scalar.ExtractBitfield(0, 0)); + ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1))); + ASSERT_TRUE(s_scalar.ExtractBitfield(len, 0)); + ASSERT_EQ(0, memcmp(&a1, s_scalar.GetBytes(), sizeof(a1))); + ASSERT_TRUE(s_scalar.ExtractBitfield(len - 4, 4)); + ASSERT_EQ(0, memcmp(&b1, s_scalar.GetBytes(), sizeof(b1))); + + unsigned long long a2 = 0xf1f2f3f4f5f6f7f8ULL; + unsigned long long b2 = 0x0f1f2f3f4f5f6f7fULL; + Scalar u_scalar(a2); + ASSERT_TRUE(u_scalar.ExtractBitfield(0, 0)); + ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2))); + ASSERT_TRUE(u_scalar.ExtractBitfield(len, 0)); + ASSERT_EQ(0, memcmp(&a2, u_scalar.GetBytes(), sizeof(a2))); + ASSERT_TRUE(u_scalar.ExtractBitfield(len - 4, 4)); + ASSERT_EQ(0, memcmp(&b2, u_scalar.GetBytes(), sizeof(b2))); +} |

