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