blob: 851d65355de834e9e12e6fb97f6a4339e6a75cb5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
// PR rtl-optimization/104869
// { dg-do run }
// { dg-options "-O2 -fvisibility=hidden -std=c++11" }
// { dg-require-visibility "" }
struct QBasicAtomicInteger {
[[gnu::noipa]] int loadRelaxed() { return 1; }
};
struct RefCount {
bool deref() {
int count = atomic.loadRelaxed();
if (count)
return false;
return deref();
}
QBasicAtomicInteger atomic;
};
struct QArrayData {
RefCount ref;
};
struct QString {
~QString();
QArrayData d;
};
int ok;
QString::~QString() { d.ref.deref(); }
struct Label {
bool isValid() { return generator; }
int *generator;
int index;
};
struct ControlFlow;
struct Codegen {
[[gnu::noipa]] bool visit();
ControlFlow *controlFlow;
};
struct ControlFlow {
enum UnwindType { EE };
struct UnwindTarget {
Label linkLabel;
};
ControlFlow *parent;
UnwindType unwindTarget_type;
UnwindTarget unwindTarget() {
QString label;
ControlFlow *flow = this;
while (flow) {
Label l = getUnwindTarget(unwindTarget_type, label);
if (l.isValid())
return {l};
flow = flow->parent;
}
return UnwindTarget();
}
[[gnu::noipa]] Label getUnwindTarget(UnwindType, QString &) {
Label l = { &ok, 0 };
return l;
}
};
[[gnu::noipa]] void foo(int) {
ok = 1;
}
[[gnu::noipa]] bool Codegen::visit() {
if (!controlFlow)
return false;
ControlFlow::UnwindTarget target = controlFlow->unwindTarget();
if (target.linkLabel.isValid())
foo(2);
return false;
}
#ifdef __hpux__
extern int main(void) __attribute__ ((visibility ("default")));
#endif
int
main() {
ControlFlow cf = { nullptr, ControlFlow::UnwindType::EE };
Codegen c = { &cf };
c.visit();
if (!ok)
__builtin_abort ();
}
|