107 lines
2.9 KiB
C++
107 lines
2.9 KiB
C++
|
// RUN: %clang++ -std=gnu++11 -O2 -g %s -o %t
|
||
|
// RUN: %dexter --fail-lt 1.0 -w \
|
||
|
// RUN: --binary %t --debugger 'lldb' -v -- %s
|
||
|
// RUN: %clang++ -std=gnu++11 -O0 -g %s -o %t
|
||
|
// RUN: %dexter --fail-lt 1.0 -w \
|
||
|
// RUN: --binary %t --debugger 'lldb' -- %s
|
||
|
|
||
|
// REQUIRES: lldb
|
||
|
// Currently getting intermittent failures on darwin.
|
||
|
// UNSUPPORTED: system-windows, system-darwin
|
||
|
|
||
|
//// Check that the debugging experience with __attribute__((optnone)) at O2
|
||
|
//// matches O0. Test simple structs and methods.
|
||
|
|
||
|
long a_global_ptr[] = { 0xCAFEBABEL, 0xFEEDBEEFL };
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
struct A {
|
||
|
int a;
|
||
|
float b;
|
||
|
|
||
|
enum B {
|
||
|
A_VALUE = 0x1,
|
||
|
B_VALUE = 0x2
|
||
|
};
|
||
|
|
||
|
struct some_data {
|
||
|
enum B other_b;
|
||
|
enum B other_other_b;
|
||
|
};
|
||
|
|
||
|
struct other_data {
|
||
|
union {
|
||
|
void *raw_ptr;
|
||
|
long *long_ptr;
|
||
|
float *float_ptr;
|
||
|
} a;
|
||
|
struct some_data b;
|
||
|
struct some_data c;
|
||
|
};
|
||
|
private:
|
||
|
struct other_data _data;
|
||
|
|
||
|
public:
|
||
|
struct other_data *getOtherData() { return &_data; }
|
||
|
|
||
|
__attribute__((always_inline,nodebug))
|
||
|
void setSomeData1(A::B value, A::B other_value) {
|
||
|
struct other_data *data = getOtherData();
|
||
|
data->b.other_b = value;
|
||
|
data->b.other_other_b = other_value;
|
||
|
}
|
||
|
|
||
|
__attribute__((always_inline))
|
||
|
void setSomeData2(A::B value, A::B other_value) {
|
||
|
struct other_data *data = getOtherData();
|
||
|
data->c.other_b = value;
|
||
|
data->c.other_other_b = other_value;
|
||
|
}
|
||
|
|
||
|
void setOtherData() {
|
||
|
setSomeData2(A_VALUE, B_VALUE);
|
||
|
getOtherData()->a.long_ptr = &a_global_ptr[0];
|
||
|
}
|
||
|
|
||
|
__attribute__((optnone))
|
||
|
A() {
|
||
|
__builtin_memset(this, 0xFF, sizeof(*this));
|
||
|
} //DexLabel('break_0')
|
||
|
// DexExpectWatchValue('a', '-1', on_line=ref('break_0'))
|
||
|
//// Check b is NaN by comparing it to itself.
|
||
|
// DexExpectWatchValue('this->b == this->b', 'false', on_line=ref('break_0'))
|
||
|
// DexExpectWatchValue('_data.a.raw_ptr == -1', 'true', on_line=ref('break_0'))
|
||
|
// DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0'))
|
||
|
// DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0'))
|
||
|
// DexExpectWatchValue('a_global_ptr[0]', 0xcafebabe, on_line=ref('break_0'))
|
||
|
// DexExpectWatchValue('a_global_ptr[1]', 0xfeedbeef, on_line=ref('break_0'))
|
||
|
|
||
|
__attribute__((optnone))
|
||
|
~A() {
|
||
|
*getOtherData()->a.long_ptr = 0xADDF00DL;
|
||
|
} //DexLabel('break_1')
|
||
|
// DexExpectWatchValue('_data.a.raw_ptr == a_global_ptr', 'true', on_line=ref('break_1'))
|
||
|
// DexExpectWatchValue('a_global_ptr[0]', 0xaddf00d, on_line=ref('break_1'))
|
||
|
|
||
|
__attribute__((optnone))
|
||
|
long getData() {
|
||
|
setSomeData1(B_VALUE, A_VALUE);
|
||
|
setOtherData();
|
||
|
return getOtherData()->a.long_ptr[1]; //DexLabel('break_2')
|
||
|
}
|
||
|
// DexExpectWatchValue('_data.b.other_b', 'B_VALUE', on_line=ref('break_2'))
|
||
|
// DexExpectWatchValue('_data.b.other_other_b', 'A_VALUE', on_line=ref('break_2'))
|
||
|
};
|
||
|
|
||
|
} // anonymous namespace
|
||
|
|
||
|
int main() {
|
||
|
int result = 0;
|
||
|
{
|
||
|
A a;
|
||
|
result = a.getData();
|
||
|
}
|
||
|
return result;
|
||
|
}
|