1 // P0145R2: Refining Expression Order for C++
2 // { dg-do run }
3 // { dg-options "-std=c++17" }
4
5 extern "C" int printf (const char *, ...);
sink(...)6 void sink(...) { }
7
8 int last = 0;
f(int i)9 int f(int i)
10 {
11 if (i < last)
12 __builtin_abort ();
13 last = i;
14 return i;
15 }
16
g(int i)17 int& g(int i)
18 {
19 static int dummy;
20 f(i);
21 return dummy;
22 }
23
24 struct A
25 {
26 int _i;
AA27 A(int i): _i(f(i)) { }
memfnA28 A& memfn(int i, int j) { f(j); return *this; }
29 int operator<<(int i) { return 0; }
30 A& operator=(const A&) { return *this; }
31 A& operator+=(int i) { return *this; }
32 };
33
34 struct B
35 {
36 int _i;
BB37 B(): _i(0) {}
BB38 B(int i): _i(f(i)) { }
39 };
40
41 int operator>>(A&, int i) { return 0; }
42
43 A a(0);
afn(int i)44 A* afn(int i)
45 {
46 f(i);
47 return &a;
48 }
49
aref(int i)50 A& aref(int i)
51 {
52 f(i);
53 return a;
54 }
55
56 B b;
bval(int i)57 B bval(int i)
58 {
59 return B(i);
60 }
61
bref(int i)62 B& bref(int i)
63 {
64 f(i);
65 return b;
66 }
67
68 static int si;
ip(int i)69 int* ip (int i)
70 {
71 f(i);
72 return &si;
73 }
74
iref(int i)75 int& iref(int i)
76 {
77 f(i);
78 return si;
79 }
80
pmff(int i)81 auto pmff(int i) {
82 f(i);
83 return &A::memfn;
84 }
85
f()86 template <class T> void f()
87 {
88 // a.b
89 A(1).memfn(f(2),3).memfn(f(4),5);
90 aref(6).memfn(f(7),8);
91 (aref(9).*pmff(10))(f(11),12);
92 last = 0;
93
94 // a->b
95 afn(12)->memfn(f(13),14);
96
97 // a->*b
98 (afn(15)->*pmff(16))(f(17),18);
99 last = 0;
100
101 // a(b)
102 // covered in eval-order1.C
103
104 // b @= a
105 aref(19)=A(18);
106 iref(21)=f(20);
107 aref(23)+=f(22);
108 bref(25)=bval(24);
109 (f(27), b) = bval(26);
110 last = 0;
111
112 int ar[4] = {};
113 int i = 0;
114 ar[i++] = i;
115 if (ar[0] != 0)
116 __builtin_abort();
117
118 // a[b]
119 afn(20)[f(21)-21].memfn(f(22),23);
120 ip(24)[f(25)-25] = 0;
121 last=0;
122
123 // a << b
124 aref(24) << f(25);
125 iref(26) << f(27);
126 last=0;
127
128 // a >> b
129 aref(26) >> f(27);
130 iref(28) >> f(29);
131 }
132
g()133 void g()
134 {
135 // a.b
136 A(1).memfn(f(2),3).memfn(f(4),5);
137 aref(6).memfn(f(7),8);
138 (aref(9).*pmff(10))(f(11),12);
139 last = 0;
140
141 // a->b
142 afn(12)->memfn(f(13),14);
143
144 // a->*b
145 (afn(15)->*pmff(16))(f(17),18);
146 last = 0;
147
148 // a(b)
149 // covered in eval-order1.C
150
151 // b @= a
152 aref(19)=A(18);
153 iref(21)=f(20);
154 aref(23)+=f(22);
155 bref(25)=bval(24);
156 (f(27), b) = bval(26);
157 last = 0;
158
159 int ar[4] = {};
160 int i = 0;
161 ar[i++] = i;
162 if (ar[0] != 0)
163 __builtin_abort();
164
165 // a[b]
166 afn(20)[f(21)-21].memfn(f(22),23);
167 ip(24)[f(25)-25] = 0;
168 last=0;
169
170 // a << b
171 aref(24) << f(25);
172 iref(26) << f(27);
173 last=0;
174
175 // a >> b
176 aref(26) >> f(27);
177 iref(28) >> f(29);
178 }
179
main()180 int main()
181 {
182 g();
183 last = 0;
184 f<int>();
185 }
186