1 // PR c++/46056 2 // Check that range-based for loop calls destructors 3 // when required 4 // { dg-do run { target c++11 } } 5 extern "C" void abort(); 6 7 int value_counter = 0, it_counter = 0, seq_counter = 0; 8 9 struct Int 10 { 11 int x; IntInt12 Int(int v) 13 :x(v) 14 { 15 ++value_counter; 16 } IntInt17 Int(const Int &o) 18 :x(o.x) 19 { 20 ++value_counter; 21 } ~IntInt22 ~Int() 23 { 24 --value_counter; 25 } 26 }; 27 28 struct iterator 29 { 30 int x; iteratoriterator31 iterator(int v) 32 :x(v) 33 { 34 ++it_counter; 35 } iteratoriterator36 iterator(const iterator &o) 37 :x(o.x) 38 { 39 ++it_counter; 40 } ~iteratoriterator41 ~iterator() 42 { 43 --it_counter; 44 } 45 iterator &operator ++() { ++x; return *this; } 46 int operator *() { return x; } 47 bool operator != (const iterator &o) { return x != o.x; } 48 }; 49 50 struct container 51 { 52 int min, max; containercontainer53 container(int a, int b) :min(a), max(b) 54 { 55 ++seq_counter; 56 } 57 container(const container &) = delete; ~containercontainer58 ~container() 59 { 60 --seq_counter; 61 } 62 }; 63 begin(container & c)64iterator begin(container &c) 65 { 66 return iterator(c.min); 67 } 68 end(container & c)69iterator end(container &c) 70 { 71 return iterator(c.max + 1); 72 } 73 main()74int main() 75 { 76 for (Int x : container(0, 10)) 77 { 78 if (value_counter != 1) abort(); 79 if (it_counter != 2) abort(); 80 if (seq_counter != 1) abort(); 81 } 82 if (value_counter != 0) abort(); 83 if (it_counter != 0) abort(); 84 if (seq_counter != 0) abort(); 85 86 try 87 { 88 for (Int x : container(0, 10)) 89 { 90 if (value_counter != 1) abort(); 91 if (it_counter != 2) abort(); 92 if (seq_counter != 1) abort(); 93 } 94 if (value_counter != 0) abort(); 95 if (it_counter != 0) abort(); 96 if (seq_counter != 0) abort(); 97 98 for (Int x : container(0, 10)) 99 { 100 if (value_counter != 1) abort(); 101 if (it_counter != 2) abort(); 102 if (seq_counter != 1) abort(); 103 104 if (x.x == 5) 105 throw 0; 106 } 107 } 108 catch (int) 109 { 110 if (value_counter != 0) abort(); 111 if (it_counter != 0) abort(); 112 if (seq_counter != 0) abort(); 113 } 114 115 return 0; 116 } 117