1 // RUN: %libomp-cxx20-compile-and-run | FileCheck %s --match-full-lines 2 3 #ifndef HEADER 4 #define HEADER 5 6 #include <cstdlib> 7 #include <cstdarg> 8 #include <cstdio> 9 #include <vector> 10 11 struct Reporter { 12 const char *name; 13 14 Reporter(const char *name) : name(name) { print("ctor"); } 15 16 Reporter() : name("<anon>") { print("ctor"); } 17 18 Reporter(const Reporter &that) : name(that.name) { print("copy ctor"); } 19 20 Reporter(Reporter &&that) : name(that.name) { print("move ctor"); } 21 22 ~Reporter() { print("dtor"); } 23 24 const Reporter &operator=(const Reporter &that) { 25 print("copy assign"); 26 this->name = that.name; 27 return *this; 28 } 29 30 const Reporter &operator=(Reporter &&that) { 31 print("move assign"); 32 this->name = that.name; 33 return *this; 34 } 35 36 struct Iterator { 37 const Reporter *owner; 38 int pos; 39 40 Iterator(const Reporter *owner, int pos) : owner(owner), pos(pos) {} 41 42 Iterator(const Iterator &that) : owner(that.owner), pos(that.pos) { 43 owner->print("iterator copy ctor"); 44 } 45 46 Iterator(Iterator &&that) : owner(that.owner), pos(that.pos) { 47 owner->print("iterator move ctor"); 48 } 49 50 ~Iterator() { owner->print("iterator dtor"); } 51 52 const Iterator &operator=(const Iterator &that) { 53 owner->print("iterator copy assign"); 54 this->owner = that.owner; 55 this->pos = that.pos; 56 return *this; 57 } 58 59 const Iterator &operator=(Iterator &&that) { 60 owner->print("iterator move assign"); 61 this->owner = that.owner; 62 this->pos = that.pos; 63 return *this; 64 } 65 66 bool operator==(const Iterator &that) const { 67 owner->print("iterator %d == %d", 2 - this->pos, 2 - that.pos); 68 return this->pos == that.pos; 69 } 70 71 Iterator &operator++() { 72 owner->print("iterator prefix ++"); 73 pos -= 1; 74 return *this; 75 } 76 77 Iterator operator++(int) { 78 owner->print("iterator postfix ++"); 79 auto result = *this; 80 pos -= 1; 81 return result; 82 } 83 84 int operator*() const { 85 int result = 2 - pos; 86 owner->print("iterator deref: %i", result); 87 return result; 88 } 89 90 size_t operator-(const Iterator &that) const { 91 int result = (2 - this->pos) - (2 - that.pos); 92 owner->print("iterator distance: %d", result); 93 return result; 94 } 95 96 Iterator operator+(int steps) const { 97 owner->print("iterator advance: %i += %i", 2 - this->pos, steps); 98 return Iterator(owner, pos - steps); 99 } 100 }; 101 102 Iterator begin() const { 103 print("begin()"); 104 return Iterator(this, 2); 105 } 106 107 Iterator end() const { 108 print("end()"); 109 return Iterator(this, -1); 110 } 111 112 void print(const char *msg, ...) const { 113 va_list args; 114 va_start(args, msg); 115 printf("[%s] ", name); 116 vprintf(msg, args); 117 printf("\n"); 118 va_end(args); 119 } 120 }; 121 122 int main() { 123 printf("do\n"); 124 #pragma omp parallel for collapse(3) num_threads(1) 125 for (int i = 0; i < 2; ++i) 126 #pragma omp interchange 127 for (Reporter c{"C"}; auto &&v : Reporter("A")) 128 for (Reporter d{"D"}; auto &&w : Reporter("B")) 129 for (int k = 0; k < 2; ++k) 130 printf("i=%d v=%d w=%d k=%d\n", i, v, w, k); 131 printf("done\n"); 132 return EXIT_SUCCESS; 133 } 134 135 #endif /* HEADER */ 136 137 // CHECK: do 138 // CHECK-NEXT: [C] ctor 139 // CHECK-NEXT: [A] ctor 140 // CHECK-NEXT: [A] end() 141 // CHECK-NEXT: [A] begin() 142 // CHECK-NEXT: [A] begin() 143 // CHECK-NEXT: [A] iterator distance: 3 144 // CHECK-NEXT: [D] ctor 145 // CHECK-NEXT: [B] ctor 146 // CHECK-NEXT: [B] end() 147 // CHECK-NEXT: [B] begin() 148 // CHECK-NEXT: [B] begin() 149 // CHECK-NEXT: [B] iterator distance: 3 150 // CHECK-NEXT: [B] iterator advance: 0 += 0 151 // CHECK-NEXT: [B] iterator move assign 152 // CHECK-NEXT: [B] iterator deref: 0 153 // CHECK-NEXT: [A] iterator advance: 0 += 0 154 // CHECK-NEXT: [A] iterator move assign 155 // CHECK-NEXT: [A] iterator deref: 0 156 // CHECK-NEXT: i=0 v=0 w=0 k=0 157 // CHECK-NEXT: i=0 v=0 w=0 k=1 158 // CHECK-NEXT: [A] iterator dtor 159 // CHECK-NEXT: [B] iterator dtor 160 // CHECK-NEXT: [B] iterator advance: 0 += 0 161 // CHECK-NEXT: [B] iterator move assign 162 // CHECK-NEXT: [B] iterator deref: 0 163 // CHECK-NEXT: [A] iterator advance: 0 += 1 164 // CHECK-NEXT: [A] iterator move assign 165 // CHECK-NEXT: [A] iterator deref: 1 166 // CHECK-NEXT: i=0 v=1 w=0 k=0 167 // CHECK-NEXT: i=0 v=1 w=0 k=1 168 // CHECK-NEXT: [A] iterator dtor 169 // CHECK-NEXT: [B] iterator dtor 170 // CHECK-NEXT: [B] iterator advance: 0 += 0 171 // CHECK-NEXT: [B] iterator move assign 172 // CHECK-NEXT: [B] iterator deref: 0 173 // CHECK-NEXT: [A] iterator advance: 0 += 2 174 // CHECK-NEXT: [A] iterator move assign 175 // CHECK-NEXT: [A] iterator deref: 2 176 // CHECK-NEXT: i=0 v=2 w=0 k=0 177 // CHECK-NEXT: i=0 v=2 w=0 k=1 178 // CHECK-NEXT: [A] iterator dtor 179 // CHECK-NEXT: [B] iterator dtor 180 // CHECK-NEXT: [B] iterator advance: 0 += 1 181 // CHECK-NEXT: [B] iterator move assign 182 // CHECK-NEXT: [B] iterator deref: 1 183 // CHECK-NEXT: [A] iterator advance: 0 += 0 184 // CHECK-NEXT: [A] iterator move assign 185 // CHECK-NEXT: [A] iterator deref: 0 186 // CHECK-NEXT: i=0 v=0 w=1 k=0 187 // CHECK-NEXT: i=0 v=0 w=1 k=1 188 // CHECK-NEXT: [A] iterator dtor 189 // CHECK-NEXT: [B] iterator dtor 190 // CHECK-NEXT: [B] iterator advance: 0 += 1 191 // CHECK-NEXT: [B] iterator move assign 192 // CHECK-NEXT: [B] iterator deref: 1 193 // CHECK-NEXT: [A] iterator advance: 0 += 1 194 // CHECK-NEXT: [A] iterator move assign 195 // CHECK-NEXT: [A] iterator deref: 1 196 // CHECK-NEXT: i=0 v=1 w=1 k=0 197 // CHECK-NEXT: i=0 v=1 w=1 k=1 198 // CHECK-NEXT: [A] iterator dtor 199 // CHECK-NEXT: [B] iterator dtor 200 // CHECK-NEXT: [B] iterator advance: 0 += 1 201 // CHECK-NEXT: [B] iterator move assign 202 // CHECK-NEXT: [B] iterator deref: 1 203 // CHECK-NEXT: [A] iterator advance: 0 += 2 204 // CHECK-NEXT: [A] iterator move assign 205 // CHECK-NEXT: [A] iterator deref: 2 206 // CHECK-NEXT: i=0 v=2 w=1 k=0 207 // CHECK-NEXT: i=0 v=2 w=1 k=1 208 // CHECK-NEXT: [A] iterator dtor 209 // CHECK-NEXT: [B] iterator dtor 210 // CHECK-NEXT: [B] iterator advance: 0 += 2 211 // CHECK-NEXT: [B] iterator move assign 212 // CHECK-NEXT: [B] iterator deref: 2 213 // CHECK-NEXT: [A] iterator advance: 0 += 0 214 // CHECK-NEXT: [A] iterator move assign 215 // CHECK-NEXT: [A] iterator deref: 0 216 // CHECK-NEXT: i=0 v=0 w=2 k=0 217 // CHECK-NEXT: i=0 v=0 w=2 k=1 218 // CHECK-NEXT: [A] iterator dtor 219 // CHECK-NEXT: [B] iterator dtor 220 // CHECK-NEXT: [B] iterator advance: 0 += 2 221 // CHECK-NEXT: [B] iterator move assign 222 // CHECK-NEXT: [B] iterator deref: 2 223 // CHECK-NEXT: [A] iterator advance: 0 += 1 224 // CHECK-NEXT: [A] iterator move assign 225 // CHECK-NEXT: [A] iterator deref: 1 226 // CHECK-NEXT: i=0 v=1 w=2 k=0 227 // CHECK-NEXT: i=0 v=1 w=2 k=1 228 // CHECK-NEXT: [A] iterator dtor 229 // CHECK-NEXT: [B] iterator dtor 230 // CHECK-NEXT: [B] iterator advance: 0 += 2 231 // CHECK-NEXT: [B] iterator move assign 232 // CHECK-NEXT: [B] iterator deref: 2 233 // CHECK-NEXT: [A] iterator advance: 0 += 2 234 // CHECK-NEXT: [A] iterator move assign 235 // CHECK-NEXT: [A] iterator deref: 2 236 // CHECK-NEXT: i=0 v=2 w=2 k=0 237 // CHECK-NEXT: i=0 v=2 w=2 k=1 238 // CHECK-NEXT: [A] iterator dtor 239 // CHECK-NEXT: [B] iterator dtor 240 // CHECK-NEXT: [B] iterator advance: 0 += 0 241 // CHECK-NEXT: [B] iterator move assign 242 // CHECK-NEXT: [B] iterator deref: 0 243 // CHECK-NEXT: [A] iterator advance: 0 += 0 244 // CHECK-NEXT: [A] iterator move assign 245 // CHECK-NEXT: [A] iterator deref: 0 246 // CHECK-NEXT: i=1 v=0 w=0 k=0 247 // CHECK-NEXT: i=1 v=0 w=0 k=1 248 // CHECK-NEXT: [A] iterator dtor 249 // CHECK-NEXT: [B] iterator dtor 250 // CHECK-NEXT: [B] iterator advance: 0 += 0 251 // CHECK-NEXT: [B] iterator move assign 252 // CHECK-NEXT: [B] iterator deref: 0 253 // CHECK-NEXT: [A] iterator advance: 0 += 1 254 // CHECK-NEXT: [A] iterator move assign 255 // CHECK-NEXT: [A] iterator deref: 1 256 // CHECK-NEXT: i=1 v=1 w=0 k=0 257 // CHECK-NEXT: i=1 v=1 w=0 k=1 258 // CHECK-NEXT: [A] iterator dtor 259 // CHECK-NEXT: [B] iterator dtor 260 // CHECK-NEXT: [B] iterator advance: 0 += 0 261 // CHECK-NEXT: [B] iterator move assign 262 // CHECK-NEXT: [B] iterator deref: 0 263 // CHECK-NEXT: [A] iterator advance: 0 += 2 264 // CHECK-NEXT: [A] iterator move assign 265 // CHECK-NEXT: [A] iterator deref: 2 266 // CHECK-NEXT: i=1 v=2 w=0 k=0 267 // CHECK-NEXT: i=1 v=2 w=0 k=1 268 // CHECK-NEXT: [A] iterator dtor 269 // CHECK-NEXT: [B] iterator dtor 270 // CHECK-NEXT: [B] iterator advance: 0 += 1 271 // CHECK-NEXT: [B] iterator move assign 272 // CHECK-NEXT: [B] iterator deref: 1 273 // CHECK-NEXT: [A] iterator advance: 0 += 0 274 // CHECK-NEXT: [A] iterator move assign 275 // CHECK-NEXT: [A] iterator deref: 0 276 // CHECK-NEXT: i=1 v=0 w=1 k=0 277 // CHECK-NEXT: i=1 v=0 w=1 k=1 278 // CHECK-NEXT: [A] iterator dtor 279 // CHECK-NEXT: [B] iterator dtor 280 // CHECK-NEXT: [B] iterator advance: 0 += 1 281 // CHECK-NEXT: [B] iterator move assign 282 // CHECK-NEXT: [B] iterator deref: 1 283 // CHECK-NEXT: [A] iterator advance: 0 += 1 284 // CHECK-NEXT: [A] iterator move assign 285 // CHECK-NEXT: [A] iterator deref: 1 286 // CHECK-NEXT: i=1 v=1 w=1 k=0 287 // CHECK-NEXT: i=1 v=1 w=1 k=1 288 // CHECK-NEXT: [A] iterator dtor 289 // CHECK-NEXT: [B] iterator dtor 290 // CHECK-NEXT: [B] iterator advance: 0 += 1 291 // CHECK-NEXT: [B] iterator move assign 292 // CHECK-NEXT: [B] iterator deref: 1 293 // CHECK-NEXT: [A] iterator advance: 0 += 2 294 // CHECK-NEXT: [A] iterator move assign 295 // CHECK-NEXT: [A] iterator deref: 2 296 // CHECK-NEXT: i=1 v=2 w=1 k=0 297 // CHECK-NEXT: i=1 v=2 w=1 k=1 298 // CHECK-NEXT: [A] iterator dtor 299 // CHECK-NEXT: [B] iterator dtor 300 // CHECK-NEXT: [B] iterator advance: 0 += 2 301 // CHECK-NEXT: [B] iterator move assign 302 // CHECK-NEXT: [B] iterator deref: 2 303 // CHECK-NEXT: [A] iterator advance: 0 += 0 304 // CHECK-NEXT: [A] iterator move assign 305 // CHECK-NEXT: [A] iterator deref: 0 306 // CHECK-NEXT: i=1 v=0 w=2 k=0 307 // CHECK-NEXT: i=1 v=0 w=2 k=1 308 // CHECK-NEXT: [A] iterator dtor 309 // CHECK-NEXT: [B] iterator dtor 310 // CHECK-NEXT: [B] iterator advance: 0 += 2 311 // CHECK-NEXT: [B] iterator move assign 312 // CHECK-NEXT: [B] iterator deref: 2 313 // CHECK-NEXT: [A] iterator advance: 0 += 1 314 // CHECK-NEXT: [A] iterator move assign 315 // CHECK-NEXT: [A] iterator deref: 1 316 // CHECK-NEXT: i=1 v=1 w=2 k=0 317 // CHECK-NEXT: i=1 v=1 w=2 k=1 318 // CHECK-NEXT: [A] iterator dtor 319 // CHECK-NEXT: [B] iterator dtor 320 // CHECK-NEXT: [B] iterator advance: 0 += 2 321 // CHECK-NEXT: [B] iterator move assign 322 // CHECK-NEXT: [B] iterator deref: 2 323 // CHECK-NEXT: [A] iterator advance: 0 += 2 324 // CHECK-NEXT: [A] iterator move assign 325 // CHECK-NEXT: [A] iterator deref: 2 326 // CHECK-NEXT: i=1 v=2 w=2 k=0 327 // CHECK-NEXT: i=1 v=2 w=2 k=1 328 // CHECK-NEXT: [A] iterator dtor 329 // CHECK-NEXT: [B] iterator dtor 330 // CHECK-NEXT: [B] iterator dtor 331 // CHECK-NEXT: [B] iterator dtor 332 // CHECK-NEXT: [B] iterator dtor 333 // CHECK-NEXT: [B] dtor 334 // CHECK-NEXT: [D] dtor 335 // CHECK-NEXT: [A] iterator dtor 336 // CHECK-NEXT: [A] iterator dtor 337 // CHECK-NEXT: [A] iterator dtor 338 // CHECK-NEXT: [A] dtor 339 // CHECK-NEXT: [C] dtor 340 // CHECK-NEXT: done 341