xref: /llvm-project/lldb/test/API/lang/cpp/static_members/TestCPPStaticMembers.py (revision ab05d9134d18db34501985a01fbfc02609767587)
1"""
2Tests that C++ member and static variables have correct layout and scope.
3"""
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class TestCase(TestBase):
13    # We fail to lookup static members on Windows.
14    @expectedFailureAll(oslist=["windows"])
15    def test_access_from_main(self):
16        self.build()
17        lldbutil.run_to_source_breakpoint(
18            self, "// stop in main", lldb.SBFileSpec("main.cpp")
19        )
20
21        self.expect_expr("my_a.m_a", result_type="short", result_value="1")
22        self.expect_expr("my_a.s_b", result_type="long", result_value="2")
23        self.expect_expr("my_a.s_c", result_type="int", result_value="3")
24
25    # We fail to lookup static members on Windows.
26    @expectedFailureAll(oslist=["windows"])
27    def test_access_from_member_function(self):
28        self.build()
29        lldbutil.run_to_source_breakpoint(
30            self, "// stop in member function", lldb.SBFileSpec("main.cpp")
31        )
32        self.expect_expr("m_a", result_type="short", result_value="1")
33        self.expect_expr("s_b", result_type="long", result_value="2")
34        self.expect_expr("s_c", result_type="int", result_value="3")
35
36    # Currently lookups find variables that are in any scope.
37    @expectedFailureAll()
38    def test_access_without_scope(self):
39        self.build()
40        self.createTestTarget()
41        self.expect(
42            "expression s_c",
43            error=True,
44            startstr="error: use of undeclared identifier 's_d'",
45        )
46
47    # We fail to lookup static members on Windows.
48    @expectedFailureAll(oslist=["windows"])
49    def test_no_crash_in_IR_arithmetic(self):
50        """
51        Test that LLDB doesn't crash on evaluating specific expression involving
52        pointer arithmetic and taking the address of a static class member.
53        See https://bugs.llvm.org/show_bug.cgi?id=52449
54        """
55        self.build()
56        lldbutil.run_to_source_breakpoint(
57            self, "// stop in main", lldb.SBFileSpec("main.cpp")
58        )
59
60        # This expression contains the following IR code:
61        # ... i64 ptrtoint (i32* @_ZN1A3s_cE to i64)) ...
62        expr = "(int*)100 + (long long)(&A::s_c)"
63
64        # The IR interpreter doesn't support non-const operands to the
65        # `GetElementPtr` IR instruction, so verify that it correctly fails to
66        # evaluate expression.
67        opts = lldb.SBExpressionOptions()
68        opts.SetAllowJIT(False)
69        value = self.target().EvaluateExpression(expr, opts)
70        self.assertTrue(value.GetError().Fail())
71        self.assertIn(
72            "Can't evaluate the expression without a running target",
73            value.GetError().GetCString(),
74        )
75
76        # Evaluating the expression via JIT should work fine.
77        value = self.target().EvaluateExpression(expr)
78        self.assertSuccess(value.GetError())
79
80    def test_IR_interpreter_can_handle_getelementptr_constants_args(self):
81        self.build()
82        lldbutil.run_to_source_breakpoint(
83            self, "// stop in main", lldb.SBFileSpec("main.cpp")
84        )
85
86        # This expression contains the following IR code:
87        # ... getelementptr inbounds [2 x i32], [2 x i32]* %4, i64 0, i64 0
88        expr = "arr[0]"
89
90        # The IR interpreter supports const operands to the `GetElementPtr` IR
91        # instruction, so it should be able to evaluate expression without JIT.
92        opts = lldb.SBExpressionOptions()
93        opts.SetAllowJIT(False)
94        value = self.target().EvaluateExpression(expr, opts)
95        self.assertSuccess(value.GetError())
96