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

Last change on this file since 15b5abac was 7d25f44, checked in by Peter A. Buhr <pabuhr@…>, 2 years ago

update files from old separator manipulator names to new names

  • Property mode set to 100644
File size: 5.3 KB
RevLine 
[32b8144]1//
[5ead9f9]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.
[32b8144]6//
7// dtor-early-exit.c --
8//
[5ead9f9]9// Author : Rob Schluntz
10// Created On : Wed Aug 17 08:26:25 2016
11// Last Modified By : Peter A. Buhr
[7d25f44]12// Last Modified On : Thu Jun 29 11:15:56 2023
13// Update Count : 11
[32b8144]14//
[5ead9f9]15
[5a5d31a]16#include <fstream.hfa>
17#include <stdlib.hfa>
[e765794]18#include <assert.h>
[85f0713]19
20struct A {
[cdbfab0]21 const char * name;
[85f0713]22 int * x;
23};
24
25// don't want these called
[2afec66]26void ?{}(A & a) { assert( false ); }
[200fcb3]27void ?{}(A & a, const char * name) { a.name = name; sout | "construct " | name; a.x = (int*)malloc(); }
[2afec66]28void ?{}(A & a, const char * name, int * ptr) { assert( false ); }
[85f0713]29
[2afec66]30A ?=?(A & a, A b) { sout | "assign " | a.name | " " | b.name; return a; }
[200fcb3]31void ?{}(A & a, A b) { sout | "copy construct " | b.name; a.x = (int*)malloc(); }
32void ^?{}(A & a) { sout | "destruct " | a.name; free(a.x); }
[85f0713]33
34// test returns
35void f(int i) {
[200fcb3]36 sout | "f i=" | i;
[85f0713]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++) {
[200fcb3]57 sout | "g for i=" | i;
[85f0713]58 A x = { "x" };
59 // construct x
60 // destruct x
61 }
[200fcb3]62 sout | nl;
[85f0713]63 {
64 int i = 0;
65 while (i < 10) {
[200fcb3]66 sout | "g while i=" | i;
[85f0713]67 A x = { "x" };
68 // construct x
69 i++;
70 // destruct x
71 }
72 }
[5ea5b28]73 sout | nl;
[85f0713]74 for (int i = 0; i < 10; i++) {
75 switch(10) {
76 case 0:
77 case 5:
78 case 10: {
79 A y = { "y" };
[200fcb3]80 sout | "g switch i=" | i;
[85f0713]81 // construct y
82 break; // destruct y
83 }
84 default: {
[200fcb3]85 sout | "g switch i=" | i;
[85f0713]86 A x = { "x" };
87 // construct x
88 break; // destruct x
89 }
90 }
91 }
[200fcb3]92 sout | nl;
[85f0713]93 for (int k = 0; k < 2; k++) {
[200fcb3]94 sout | "g for k=" | k;
[85f0713]95 L1: for (int i = 0; i < 10; i++) {
[200fcb3]96 sout | "g for i=" | i;
[85f0713]97
98 A x = { "x" };
99 if (i == 2) {
[200fcb3]100 sout | "continue L1";
[85f0713]101 continue; // destruct x
102 } else if (i == 3) {
[200fcb3]103 sout | "break L1";
[85f0713]104 break; // destruct x
105 }
106
107 L2: for (int j = 0; j < 10; j++) {
[200fcb3]108 sout | "g for j=" | j;
[85f0713]109 A y = { "y" };
110 if (j == 0) {
[200fcb3]111 sout | "continue L2";
[85f0713]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) {
[200fcb3]114 sout | "break L2";
[85f0713]115 break; // destruct y
116 } else if (i == 1) {
[200fcb3]117 sout | "continue L1";
[85f0713]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) {
[200fcb3]120 sout | "break L1";
[85f0713]121 break L1; // destruct x,y
122 }
123 }
124 }
125 }
[540b275]126
[200fcb3]127 sout | nl;
[540b275]128 L3: if( 3 ) {
129 A w = { "w" };
130 if( 4 ) {
131 A v = { "v" };
[200fcb3]132 sout | "break L3";
[540b275]133 break L3;
134 }
135 }
[85f0713]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
[200fcb3]146 sout | "h";
[85f0713]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 }
[200fcb3]154 L1: sout | "L1";
[85f0713]155 A x = { "x" };
156 // S_L2 = { y, x }
[200fcb3]157 L2: sout | "L2";
[85f0713]158 if (i == 0) {
159 ++i;
[200fcb3]160 sout | "goto L1";
[85f0713]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;
[200fcb3]167 sout | "goto L2";
[85f0713]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;
[200fcb3]174 sout | "goto L3";
[85f0713]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" };
[200fcb3]182 sout | "goto L3-2";
[85f0713]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;
[200fcb3]189 sout | "goto L4";
[85f0713]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 }
[200fcb3]196 L3: sout | "L3";
197 sout | "goto L2-2";
[85f0713]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 = {}
[200fcb3]204 L4: sout | "L4";
[85f0713]205 if (i == 4) {
[200fcb3]206 sout | "goto L0";
[85f0713]207 // S_G = {}
208 goto L0;
209 // S_L-S_G = {}
210 // S_G-S_L = {}
211 }
212#ifdef ERR2
[32b8144]213 // S_G = {}
[85f0713]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
[397c101a]219void i() {
220 // potential loop
221 for() {
222 if(true) continue;
223 int t = 0;
224 }
225}
226
[5809461]227// TODO: implement __label__ and uncomment these lines
228void computedGoto() {
229 // __label__ bar;
230 void *ptr;
231 ptr = &&foo;
232 goto *ptr;
233 assert(false);
234foo: ;
235// void f() {
236// ptr = &&bar;
237// goto *ptr;
238// assert(false);
239// }
240// f();
241// assert(false);
242// bar: ;
243}
244
[85f0713]245int main() {
[7d25f44]246 sepOff(sout);
[85f0713]247 for (int i = 0; i < 4; i++) {
248 f(i);
249 }
[200fcb3]250 sout | nl;
[85f0713]251 g();
[200fcb3]252 sout | nl;
[85f0713]253 h();
[5809461]254
255 computedGoto();
[85f0713]256}
[5ead9f9]257
258// Local Variables: //
259// tab-width: 4 //
260// compile-command: "cfa dtor-early-exit" //
261// End: //
Note: See TracBrowser for help on using the repository browser.