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