source: tests/raii/dtor-early-exit.cfa@ d88f8b3b

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since d88f8b3b was 25cdca5, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

  • Property mode set to 100644
File size: 5.3 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// dtor-early-exit.c --
8//
9// Author : Rob Schluntz
10// Created On : Wed Aug 17 08:26:25 2016
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri Dec 21 08:45:19 2018
13// Update Count : 10
14//
15
16#include <fstream.hfa>
17#include <stdlib.hfa>
18#include <assert.h>
19
20struct A {
21 const char * name;
22 int * x;
23};
24
25// don't want these called
26void ?{}(A & a) { assert( false ); }
27void ?{}(A & a, const char * name) { a.name = name; sout | "construct " | name; a.x = (int*)malloc(); }
28void ?{}(A & a, const char * name, int * ptr) { assert( false ); }
29
30A ?=?(A & a, A b) { sout | "assign " | a.name | " " | b.name; return a; }
31void ?{}(A & a, A b) { sout | "copy construct " | b.name; a.x = (int*)malloc(); }
32void ^?{}(A & a) { sout | "destruct " | a.name; free(a.x); }
33
34// test returns
35void f(int i) {
36 sout | "f i=" | i;
37 A x = { "x" }; // construct x
38 {
39 A y = { "y" }; // construct y
40 {
41 A z = { "z" }; // construct z
42 {
43 if (i == 0) return; // destruct x, y, z
44 }
45 if (i == 1) return; // destruct x, y, z
46 // destruct z
47 }
48 if (i == 2) return; // destruct x, y
49 // destruct y
50 }
51 return; // destruct x
52}
53
54// test loops, switch, etc.
55void g() {
56 for (int i = 0; i < 10; i++) {
57 sout | "g for i=" | i;
58 A x = { "x" };
59 // construct x
60 // destruct x
61 }
62 sout | nl;
63 {
64 int i = 0;
65 while (i < 10) {
66 sout | "g while i=" | i;
67 A x = { "x" };
68 // construct x
69 i++;
70 // destruct x
71 }
72 }
73 sout | nl;
74 for (int i = 0; i < 10; i++) {
75 switch(10) {
76 case 0:
77 case 5:
78 case 10: {
79 A y = { "y" };
80 sout | "g switch i=" | i;
81 // construct y
82 break; // destruct y
83 }
84 default: {
85 sout | "g switch i=" | i;
86 A x = { "x" };
87 // construct x
88 break; // destruct x
89 }
90 }
91 }
92 sout | nl;
93 for (int k = 0; k < 2; k++) {
94 sout | "g for k=" | k;
95 L1: for (int i = 0; i < 10; i++) {
96 sout | "g for i=" | i;
97
98 A x = { "x" };
99 if (i == 2) {
100 sout | "continue L1";
101 continue; // destruct x
102 } else if (i == 3) {
103 sout | "break L1";
104 break; // destruct x
105 }
106
107 L2: for (int j = 0; j < 10; j++) {
108 sout | "g for j=" | j;
109 A y = { "y" };
110 if (j == 0) {
111 sout | "continue L2";
112 continue; // destruct y - missing because object that needs to be destructed is not a part of this block, it's a part of the for's block
113 } else if (j == 1) {
114 sout | "break L2";
115 break; // destruct y
116 } else if (i == 1) {
117 sout | "continue L1";
118 continue L1; // destruct x,y - note: continue takes you to destructors for block, so only generate destructor for y
119 } else if (k == 1) {
120 sout | "break L1";
121 break L1; // destruct x,y
122 }
123 }
124 }
125 }
126
127 sout | nl;
128 L3: if( 3 ) {
129 A w = { "w" };
130 if( 4 ) {
131 A v = { "v" };
132 sout | "break L3";
133 break L3;
134 }
135 }
136}
137
138// test goto
139void h() {
140 int i = 0;
141 // for each goto G with target label L:
142 // * find all constructed variables alive at G (set S_G)
143 // * find all constructed variables alive at L (set S_L)
144 // * if S_L-S_G is non-empty, error
145 // * emit destructors for all variables in S_G-S_L
146 sout | "h";
147 {
148 L0: ;
149#ifdef ERR1
150 goto L1; // this is an error in g++ because it skips initialization of y
151#endif
152 A y = { "y" };
153 // S_L1 = { y }
154 L1: sout | "L1";
155 A x = { "x" };
156 // S_L2 = { y, x }
157 L2: sout | "L2";
158 if (i == 0) {
159 ++i;
160 sout | "goto L1";
161 // S_G = { y, x }
162 goto L1; // jump back, destruct b/c before x definition
163 // S_L-S_G = {} => no error
164 // S_G-S_L = { x } => destruct x
165 } else if (i == 1) {
166 ++i;
167 sout | "goto L2";
168 // S_G = { y, x }
169 goto L2; // jump back, do not destruct
170 // S_L-S_G = {}
171 // S_G-S_L = {} => destruct nothing
172 } else if (i == 2) {
173 ++i;
174 sout | "goto L3";
175 // S_G = { y, x }
176 goto L3; // jump ahead, do not destruct
177 // S_L-S_G = {}
178 // S_G-S_L = {}
179 } else if (false) {
180 ++i;
181 A z = { "z" };
182 sout | "goto L3-2";
183 // S_G = { z, y, x }
184 goto L3;
185 // S_L-S_G = {}
186 // S_G-S_L = {z} => destruct z
187 } else {
188 ++i;
189 sout | "goto L4";
190 // S_G = { y, x }
191 goto L4; // jump ahead, destruct b/c left block x was defined in
192 // S_L-S_G = {}
193 // S_G-S_L = { y, x } => destruct y, x
194 }
195 // S_L3 = { y, x }
196 L3: sout | "L3";
197 sout | "goto L2-2";
198 // S_G = { y, x }
199 goto L2; // jump back, do not destruct
200 // S_L-S_G = {}
201 // S_G-S_L = {}
202 }
203 // S_L4 = {}
204 L4: sout | "L4";
205 if (i == 4) {
206 sout | "goto L0";
207 // S_G = {}
208 goto L0;
209 // S_L-S_G = {}
210 // S_G-S_L = {}
211 }
212#ifdef ERR2
213 // S_G = {}
214 if (i == 5) goto L2; // this is an error in g++ because it skips initialization of y, x
215 // S_L-S_G = { y, x } => non-empty, so error
216#endif
217}
218
219// TODO: implement __label__ and uncomment these lines
220void computedGoto() {
221 // __label__ bar;
222 void *ptr;
223 ptr = &&foo;
224 goto *ptr;
225 assert(false);
226foo: ;
227// void f() {
228// ptr = &&bar;
229// goto *ptr;
230// assert(false);
231// }
232// f();
233// assert(false);
234// bar: ;
235}
236
237int main() {
238 sepDisable(sout);
239 for (int i = 0; i < 4; i++) {
240 f(i);
241 }
242 sout | nl;
243 g();
244 sout | nl;
245 h();
246
247 computedGoto();
248}
249
250// Local Variables: //
251// tab-width: 4 //
252// compile-command: "cfa dtor-early-exit" //
253// End: //
Note: See TracBrowser for help on using the repository browser.