Author: Raphael Isemann Date: 2021-10-25T18:19:26+02:00 New Revision: 974c2f5e22112659549a54ff95ee310a1aac469d
URL: https://github.com/llvm/llvm-project/commit/974c2f5e22112659549a54ff95ee310a1aac469d DIFF: https://github.com/llvm/llvm-project/commit/974c2f5e22112659549a54ff95ee310a1aac469d.diff LOG: [lldb] Modernize and expand TestCppBitfields * clang-format test source. * Removed the dead setup code. * Using expect_expr etc. instead of raw expect. * Slightly expanded with tests for vtable pointers (which mostly just crash atm.) * Removed some other minor test guideline problems. Added: Modified: lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py lldb/test/API/lang/cpp/bitfields/main.cpp Removed: ################################################################################ diff --git a/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py b/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py index c67446f47803..4cdaf32ca065 100644 --- a/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py +++ b/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py @@ -10,143 +10,165 @@ class CppBitfieldsTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) - def setUp(self): - # Call super's setUp(). - TestBase.setUp(self) - # Find the line number to break inside main(). - self.line = line_number('main.cpp', '// Set break point at this line.') - - def test_and_run_command(self): - """Test 'frame variable ...' on a variable with bitfields.""" + @no_debug_info_test + def test_bitfields(self): self.build() - - lldbutil.run_to_source_breakpoint(self, '// Set break point at this line.', - lldb.SBFileSpec("main.cpp", False)) - - # The stop reason of the thread should be breakpoint. - self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, - substrs=['stopped', - 'stop reason = breakpoint']) - - # The breakpoint should have a hit count of 1. - self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, - substrs=[' resolved, hit count = 1']) - - self.expect("expr (lba.a)", VARIABLES_DISPLAYED_CORRECTLY, - substrs=['unsigned int', '2']) - self.expect("expr (lbb.b)", VARIABLES_DISPLAYED_CORRECTLY, - substrs=['unsigned int', '3']) - self.expect("expr (lbc.c)", VARIABLES_DISPLAYED_CORRECTLY, - substrs=['unsigned int', '4']) - self.expect("expr (lbd.a)", VARIABLES_DISPLAYED_CORRECTLY, - substrs=['unsigned int', '5']) - self.expect("expr (clang_example.f.a)", VARIABLES_DISPLAYED_CORRECTLY, - substrs=['uint64_t', '1']) - - self.expect("expr uwbf", - substrs=['a = 255', - 'b = 65535', - 'c = 4294967295', - 'x = 4294967295'] ) - - self.expect("expr uwubf", - substrs=['a = 16777215', - 'x = 4294967295'] ) - - self.expect( - "frame variable --show-types lba", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - '(int:32) = ', - '(unsigned int:20) a = 2', - ]) - - self.expect( - "frame variable --show-types lbb", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - '(unsigned int:1) a = 1', - '(int:31) =', - '(unsigned int:20) b = 3', - ]) - - self.expect( - "frame variable --show-types lbc", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - '(int:22) =', - '(unsigned int:1) a = 1', - '(unsigned int:1) b = 0', - '(unsigned int:5) c = 4', - '(unsigned int:1) d = 1', - '(int:2) =', - '(unsigned int:20) e = 20', - ]) - - self.expect( - "frame variable --show-types lbd", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - '(char[3]) arr = "ab"', - '(int:32) =', - '(unsigned int:20) a = 5', - ]) - - self.expect( - "frame variable --show-types clang_example", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - '(int:22) =', - '(uint64_t:1) a = 1', - '(uint64_t:1) b = 0', - '(uint64_t:1) c = 1', - '(uint64_t:1) d = 0', - '(uint64_t:1) e = 1', - '(uint64_t:1) f = 0', - '(uint64_t:1) g = 1', - '(uint64_t:1) h = 0', - '(uint64_t:1) i = 1', - '(uint64_t:1) j = 0', - '(uint64_t:1) k = 1', - ]) - - self.expect( - "frame variable --show-types derived", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - '(uint32_t) b_a = 2', - '(uint32_t:1) d_a = 1', - ]) - - self.expect( - "frame variable --show-types bb", - VARIABLES_DISPLAYED_CORRECTLY, - substrs=[ - '(bool:1) a = true', - '(bool:1) b = false', - '(bool:2) c = true', - '(bool:2) d = true', - ]) + lldbutil.run_to_source_breakpoint(self, '// break here', + lldb.SBFileSpec("main.cpp", False)) + + # Accessing LargeBitsA. + self.expect_expr("lba", result_children=[ + ValueCheck(name="", type="int:32"), + ValueCheck(name="a", type="unsigned int:20", value="2") + ]) + self.expect_expr("lba.a", result_type="unsigned int", result_value="2") + + + # Accessing LargeBitsB. + self.expect_expr("lbb", result_children=[ + ValueCheck(name="a", type="unsigned int:1", value="1"), + ValueCheck(name="", type="int:31"), + ValueCheck(name="b", type="unsigned int:20", value="3") + ]) + self.expect_expr("lbb.b", result_type="unsigned int", result_value="3") + + + # Accessing LargeBitsC. + self.expect_expr("lbc", result_children=[ + ValueCheck(name="", type="int:22"), + ValueCheck(name="a", type="unsigned int:1", value="1"), + ValueCheck(name="b", type="unsigned int:1", value="0"), + ValueCheck(name="c", type="unsigned int:5", value="4"), + ValueCheck(name="d", type="unsigned int:1", value="1"), + ValueCheck(name="", type="int:2"), + ValueCheck(name="e", type="unsigned int:20", value="20"), + ]) + self.expect_expr("lbc.c", result_type="unsigned int", result_value="4") + + + # Accessing LargeBitsD. + self.expect_expr("lbd", result_children=[ + ValueCheck(name="arr", type="char[3]", summary='"ab"'), + ValueCheck(name="", type="int:32"), + ValueCheck(name="a", type="unsigned int:20", value="5") + ]) + self.expect_expr("lbd.a", result_type="unsigned int", result_value="5") + + + # Test BitfieldsInStructInUnion. + # FIXME: This needs some more explanation for what it's actually testing. + nested_struct_children = [ + ValueCheck(name="", type="int:22"), + ValueCheck(name="a", type="uint64_t:1", value="1"), + ValueCheck(name="b", type="uint64_t:1", value="0"), + ValueCheck(name="c", type="uint64_t:1", value="1"), + ValueCheck(name="d", type="uint64_t:1", value="0"), + ValueCheck(name="e", type="uint64_t:1", value="1"), + ValueCheck(name="f", type="uint64_t:1", value="0"), + ValueCheck(name="g", type="uint64_t:1", value="1"), + ValueCheck(name="h", type="uint64_t:1", value="0"), + ValueCheck(name="i", type="uint64_t:1", value="1"), + ValueCheck(name="j", type="uint64_t:1", value="0"), + ValueCheck(name="k", type="uint64_t:1", value="1") + ] + self.expect_expr("bitfields_in_struct_in_union", + result_type="BitfieldsInStructInUnion", + result_children=[ValueCheck(name="", children=[ + ValueCheck(name="f", children=nested_struct_children) + ])] + ) + self.expect_expr("bitfields_in_struct_in_union.f.a", + result_type="uint64_t", result_value="1") + + + # Unions with bitfields. + self.expect_expr("uwbf", result_type="UnionWithBitfields", result_children=[ + ValueCheck(name="a", value="255"), + ValueCheck(name="b", value="65535"), + ValueCheck(name="c", value="4294967295"), + ValueCheck(name="x", value="4294967295") + ]) + self.expect_expr("uwubf", result_type="UnionWithUnnamedBitfield", + result_children=[ + ValueCheck(name="a", value="16777215"), + ValueCheck(name="x", value="4294967295") + ] + ) + + # Class with a base class and a bitfield. + self.expect_expr("derived", result_type="Derived", result_children=[ + ValueCheck(name="Base", children=[ + ValueCheck(name="b_a", value="2", type="uint32_t") + ]), + ValueCheck(name="d_a", value="1", type="uint32_t:1") + ]) + + + # Struct with bool bitfields. + self.expect_expr("bb", result_type="", result_children=[ + ValueCheck(name="a", value="true", type="bool:1"), + ValueCheck(name="b", value="false", type="bool:1"), + ValueCheck(name="c", value="true", type="bool:2"), + ValueCheck(name="d", value="true", type="bool:2") + ]) bb = self.frame().FindVariable('bb') - self.assertTrue(bb.IsValid()) + self.assertSuccess(bb.GetError()) bb_a = bb.GetChildAtIndex(0) - self.assertTrue(bb_a.IsValid()) + self.assertSuccess(bb_a.GetError()) self.assertEqual(bb_a.GetValueAsUnsigned(), 1) self.assertEqual(bb_a.GetValueAsSigned(), 1) bb_b = bb.GetChildAtIndex(1) - self.assertTrue(bb_b.IsValid()) + self.assertSuccess(bb_b.GetError()) self.assertEqual(bb_b.GetValueAsUnsigned(), 0) self.assertEqual(bb_b.GetValueAsSigned(), 0) bb_c = bb.GetChildAtIndex(2) - self.assertTrue(bb_c.IsValid()) + self.assertSuccess(bb_c.GetError()) self.assertEqual(bb_c.GetValueAsUnsigned(), 1) self.assertEqual(bb_c.GetValueAsSigned(), 1) bb_d = bb.GetChildAtIndex(3) - self.assertTrue(bb_d.IsValid()) + self.assertSuccess(bb_d.GetError()) self.assertEqual(bb_d.GetValueAsUnsigned(), 1) self.assertEqual(bb_d.GetValueAsSigned(), 1) + + # Test a class with a base class that has a vtable ptr. The derived + # class has bitfields. + base_with_vtable_children = [ + ValueCheck(name="a", type="unsigned int:4", value="5"), + ValueCheck(name="b", type="unsigned int:4", value="0"), + ValueCheck(name="c", type="unsigned int:4", value="5") + ] + self.expect_expr("base_with_vtable", result_children=base_with_vtable_children) + self.expect_var_path("base_with_vtable", children=base_with_vtable_children) + + # FIXME: These all crash due the vtable ptr. + @skipIf + @no_debug_info_test + def test_bitfield_behind_vtable_ptr(self): + self.build() + lldbutil.run_to_source_breakpoint(self, '// break here', + lldb.SBFileSpec("main.cpp", False)) + + # Test a class with a vtable ptr and bitfields. + with_vtable_children = [ + ValueCheck(name="a", type="unsigned int:4", value="5"), + ValueCheck(name="b", type="unsigned int:4", value="0"), + ValueCheck(name="c", type="unsigned int:4", value="5") + ] + self.expect_expr("with_vtable", result_children=with_vtable_children) + self.expect_var_path("with_vtable", children=with_vtable_children) + + # Test a class with a vtable ptr and unnamed bitfield directly after. + with_vtable_and_unnamed_children = [ + ValueCheck(name="", type="unsigned int:4", value="0"), + ValueCheck(name="b", type="unsigned int:4", value="0"), + ValueCheck(name="c", type="unsigned int:4", value="5") + ] + self.expect_expr("with_vtable_and_unnamed", + result_children=with_vtable_and_unnamed_children) + self.expect_var_path("with_vtable_and_unnamed", + children=with_vtable_and_unnamed_children) diff --git a/lldb/test/API/lang/cpp/bitfields/main.cpp b/lldb/test/API/lang/cpp/bitfields/main.cpp index a9887b5e826e..e40f1648ac83 100644 --- a/lldb/test/API/lang/cpp/bitfields/main.cpp +++ b/lldb/test/API/lang/cpp/bitfields/main.cpp @@ -1,87 +1,119 @@ #include <stdint.h> -int main(int argc, char const *argv[]) { - struct LargeBitsA { - unsigned int : 30, a : 20; - } lba; - - struct LargeBitsB { - unsigned int a : 1, : 11, : 12, b : 20; - } lbb; - - struct LargeBitsC { - unsigned int : 13, : 9, a : 1, b : 1, c : 5, d : 1, e : 20; - } lbc; - - struct LargeBitsD { - char arr[3]; - unsigned int : 30, a : 20; - } lbd; - - // This case came up when debugging clang and models RecordDeclBits - struct BitExampleFromClangDeclContext { - class fields { - uint64_t : 13; - uint64_t : 9; - - uint64_t a: 1; - uint64_t b: 1; - uint64_t c: 1; - uint64_t d: 1; - uint64_t e: 1; - uint64_t f: 1; - uint64_t g: 1; - uint64_t h: 1; - uint64_t i: 1; - uint64_t j: 1; - uint64_t k: 1; - - // In order to reproduce the crash for this case we need the - // members of fields to stay private :-( - friend struct BitExampleFromClangDeclContext; - }; - - union { - struct fields f; - }; - - BitExampleFromClangDeclContext() { - f.a = 1; - f.b = 0; - f.c = 1; - f.d = 0; - f.e = 1; - f.f = 0; - f.g = 1; - f.h = 0; - f.i = 1; - f.j = 0; - f.k = 1; - } - } clang_example; - - class B { - public: - uint32_t b_a; +struct LargeBitsA { + unsigned int : 30, a : 20; +} lba; + +struct LargeBitsB { + unsigned int a : 1, : 11, : 12, b : 20; +} lbb; + +struct LargeBitsC { + unsigned int : 13, : 9, a : 1, b : 1, c : 5, d : 1, e : 20; +} lbc; + +struct LargeBitsD { + char arr[3]; + unsigned int : 30, a : 20; +} lbd; + +struct BitfieldsInStructInUnion { + class fields { + uint64_t : 13; + uint64_t : 9; + + uint64_t a : 1; + uint64_t b : 1; + uint64_t c : 1; + uint64_t d : 1; + uint64_t e : 1; + uint64_t f : 1; + uint64_t g : 1; + uint64_t h : 1; + uint64_t i : 1; + uint64_t j : 1; + uint64_t k : 1; + + // In order to reproduce the crash for this case we need the + // members of fields to stay private :-( + friend struct BitfieldsInStructInUnion; }; - class D : public B { - public: - uint32_t d_a : 1; - } derived; - - union union_with_bitfields { - unsigned int a : 8; - unsigned int b : 16; - unsigned int c : 32; - unsigned int x; - } uwbf; + union { + struct fields f; + }; - union union_with_unnamed_bitfield { - unsigned int : 16, a : 24; - unsigned int x; - } uwubf; + BitfieldsInStructInUnion() { + f.a = 1; + f.b = 0; + f.c = 1; + f.d = 0; + f.e = 1; + f.f = 0; + f.g = 1; + f.h = 0; + f.i = 1; + f.j = 0; + f.k = 1; + } +} bitfields_in_struct_in_union; + +class Base { +public: + uint32_t b_a; +}; + +class Derived : public Base { +public: + uint32_t d_a : 1; +} derived; + +union UnionWithBitfields { + unsigned int a : 8; + unsigned int b : 16; + unsigned int c : 32; + unsigned int x; +} uwbf; + +union UnionWithUnnamedBitfield { + unsigned int : 16, a : 24; + unsigned int x; +} uwubf; + +struct BoolBits { + bool a : 1; + bool b : 1; + bool c : 2; + bool d : 2; +}; + +struct WithVTable { + virtual ~WithVTable() {} + unsigned a : 4; + unsigned b : 4; + unsigned c : 4; +}; +WithVTable with_vtable; + +struct WithVTableAndUnnamed { + virtual ~WithVTableAndUnnamed() {} + unsigned a : 4; + unsigned b : 4; + unsigned c : 4; +}; +WithVTableAndUnnamed with_vtable_and_unnamed; + +struct BaseWithVTable { + virtual ~BaseWithVTable() {} +}; +struct HasBaseWithVTable : BaseWithVTable { + unsigned a : 4; + unsigned b : 4; + unsigned c : 4; +}; +HasBaseWithVTable base_with_vtable; +int main(int argc, char const *argv[]) { lba.a = 2; lbb.a = 1; @@ -104,17 +136,23 @@ int main(int argc, char const *argv[]) { uwbf.x = 0xFFFFFFFF; uwubf.x = 0xFFFFFFFF; - struct BoolBits { - bool a : 1; - bool b : 1; - bool c : 2; - bool d : 2; - } bb; - + BoolBits bb; bb.a = 0b1; bb.b = 0b0; bb.c = 0b11; bb.d = 0b01; - return 0; // Set break point at this line. + with_vtable.a = 5; + with_vtable.b = 0; + with_vtable.c = 5; + + with_vtable_and_unnamed.a = 5; + with_vtable_and_unnamed.b = 0; + with_vtable_and_unnamed.c = 5; + + base_with_vtable.a = 5; + base_with_vtable.b = 0; + base_with_vtable.c = 5; + + return 0; // break here } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits