source: src/tests/dtor-early-exit.c@ 16988e8

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 16988e8 was cdbfab0, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

Remove unsafe void * constructors and assignment operators from prelude [closes #24] [fixes #51]

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