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