1import lldb
2from lldbsuite.test.decorators import *
3from lldbsuite.test.lldbtest import *
4from lldbsuite.test import lldbutil
5
6class StaticInitializers(TestBase):
7
8    mydir = TestBase.compute_mydir(__file__)
9
10    @expectedFailureAll(archs="aarch64", oslist=["freebsd", "linux"],
11                        bugnumber="https://bugs.llvm.org/show_bug.cgi?id=44053")
12    def test(self):
13        """ Test a static initializer. """
14        self.build()
15
16        lldbutil.run_to_source_breakpoint(self, '// break here',
17                lldb.SBFileSpec("main.cpp", False))
18
19        # We use counter to observe if the initializer was called.
20        self.expect_expr("counter", result_type="int", result_value="0")
21        self.expect("expr -p -- struct Foo { Foo() { inc_counter(); } }; Foo f;")
22        self.expect_expr("counter", result_type="int", result_value="1")
23
24    def test_failing_init(self):
25        """ Test a static initializer that fails to execute. """
26        self.build()
27
28        lldbutil.run_to_source_breakpoint(self, '// break here',
29                lldb.SBFileSpec("main.cpp", False))
30
31        # FIXME: This error message is not even remotely helpful.
32        self.expect("expr -p -- struct Foo2 { Foo2() { do_abort(); } }; Foo2 f;", error=True,
33                    substrs=["error: couldn't run static initializer:"])
34
35    def test_without_process(self):
36        """ Test a static initializer without a running process. """
37        self.expect("expr -p -- int i = 0; struct Foo3 { Foo3() { ++i; } }; Foo3 f;", error=True,
38                    substrs=["Top-level code needs to be inserted into a runnable target"])
39