1 | // RUN: %clang++ -std=gnu++11 -O2 -g %s -o %t |
2 | // RUN: %dexter --fail-lt 1.0 -w \ |
3 | // RUN: --binary %t --debugger 'lldb' -v -- %s |
4 | // RUN: %clang++ -std=gnu++11 -O0 -g %s -o %t |
5 | // RUN: %dexter --fail-lt 1.0 -w \ |
6 | // RUN: --binary %t --debugger 'lldb' -- %s |
7 | |
8 | // REQUIRES: lldb |
9 | // Currently getting intermittent failures on darwin. |
10 | // UNSUPPORTED: system-windows, system-darwin |
11 | |
12 | //// Check that the debugging experience with __attribute__((optnone)) at O2 |
13 | //// matches O0. Test simple structs and methods. |
14 | |
15 | long a_global_ptr[] = { 0xCAFEBABEL, 0xFEEDBEEFL }; |
16 | |
17 | namespace { |
18 | |
19 | struct A { |
20 | int a; |
21 | float b; |
22 | |
23 | enum B { |
24 | A_VALUE = 0x1, |
25 | B_VALUE = 0x2 |
26 | }; |
27 | |
28 | struct some_data { |
29 | enum B other_b; |
30 | enum B other_other_b; |
31 | }; |
32 | |
33 | struct other_data { |
34 | union { |
35 | void *raw_ptr; |
36 | long *long_ptr; |
37 | float *float_ptr; |
38 | } a; |
39 | struct some_data b; |
40 | struct some_data c; |
41 | }; |
42 | private: |
43 | struct other_data _data; |
44 | |
45 | public: |
46 | struct other_data *getOtherData() { return &_data; } |
47 | |
48 | __attribute__((always_inline,nodebug)) |
49 | void setSomeData1(A::B value, A::B other_value) { |
50 | struct other_data *data = getOtherData(); |
51 | data->b.other_b = value; |
52 | data->b.other_other_b = other_value; |
53 | } |
54 | |
55 | __attribute__((always_inline)) |
56 | void setSomeData2(A::B value, A::B other_value) { |
57 | struct other_data *data = getOtherData(); |
58 | data->c.other_b = value; |
59 | data->c.other_other_b = other_value; |
60 | } |
61 | |
62 | void setOtherData() { |
63 | setSomeData2(value: A_VALUE, other_value: B_VALUE); |
64 | getOtherData()->a.long_ptr = &a_global_ptr[0]; |
65 | } |
66 | |
67 | __attribute__((optnone)) |
68 | A() { |
69 | __builtin_memset(this, 0xFF, sizeof(*this)); |
70 | } //DexLabel('break_0') |
71 | // DexExpectWatchValue('a', '-1', on_line=ref('break_0')) |
72 | //// Check b is NaN by comparing it to itself. |
73 | // DexExpectWatchValue('this->b == this->b', 'false', on_line=ref('break_0')) |
74 | // DexExpectWatchValue('_data.a.raw_ptr == -1', 'true', on_line=ref('break_0')) |
75 | // DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0')) |
76 | // DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0')) |
77 | // DexExpectWatchValue('a_global_ptr[0]', 0xcafebabe, on_line=ref('break_0')) |
78 | // DexExpectWatchValue('a_global_ptr[1]', 0xfeedbeef, on_line=ref('break_0')) |
79 | |
80 | __attribute__((optnone)) |
81 | ~A() { |
82 | *getOtherData()->a.long_ptr = 0xADDF00DL; |
83 | } //DexLabel('break_1') |
84 | // DexExpectWatchValue('_data.a.raw_ptr == a_global_ptr', 'true', on_line=ref('break_1')) |
85 | // DexExpectWatchValue('a_global_ptr[0]', 0xaddf00d, on_line=ref('break_1')) |
86 | |
87 | __attribute__((optnone)) |
88 | long getData() { |
89 | setSomeData1(value: B_VALUE, other_value: A_VALUE); |
90 | setOtherData(); |
91 | return getOtherData()->a.long_ptr[1]; //DexLabel('break_2') |
92 | } |
93 | // DexExpectWatchValue('_data.b.other_b', 'B_VALUE', on_line=ref('break_2')) |
94 | // DexExpectWatchValue('_data.b.other_other_b', 'A_VALUE', on_line=ref('break_2')) |
95 | }; |
96 | |
97 | } // anonymous namespace |
98 | |
99 | int main() { |
100 | int result = 0; |
101 | { |
102 | A a; |
103 | result = a.getData(); |
104 | } |
105 | return result; |
106 | } |
107 | |