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)65 iterator begin(container &c)
66 {
67     return iterator(c.min);
68 }
69 
end(container & c)70 iterator end(container &c)
71 {
72     return iterator(c.max + 1);
73 }
74 
main()75 int 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