source: src/tests/init_once.c@ d88f256a

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 d88f256a was 72e9222, checked in by Rob Schluntz <rschlunt@…>, 9 years ago

change codegen for function-scoped static variable destruction to eliminate memory errors

  • Property mode set to 100644
File size: 3.8 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 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// init_once.c --
8//
9// Author : Rob Schluntz
10// Created On : Tue Jun 14 15:43:35 2016
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Jul 9 11:30:29 2016
13// Update Count : 3
14//
15
16// want to ensure ctor/dtor called at most once per object.
17// whole point of ctor/dtor is that you don't know what's in
18// memory when it's first called, so can't rely on member to
19// determine if this is true. instead, keep an array
20// of addresses that have been constructed and remove the element
21// when it's destructed (and vice-versa)
22
23//*** setup
24extern "C" {
25#define NULL 0
26void * malloc(size_t);
27void free(void *);
28#define assert(cond) if (! (cond)) { printf("Assertion failed: (%s) at %s:%d\n", #cond, __FILE__, __LINE__); abort(); }
29void *memset(void *s, int c, size_t n);
30}
31
32// dummy type
33struct init_once { int * x; };
34
35// array and operations
36// const int size = 1024;
37#define size 1024
38struct array {
39 init_once * elems[size];
40 int length;
41};
42void remove(array * arr, init_once * x) {
43 for (int i = 0; i < arr->length; i++) {
44 if ( arr->elems[i] == x ) {
45 arr->elems[i] = arr->elems[--arr->length];
46 return;
47 }
48 }
49}
50void insert(array * arr, init_once * x) {
51 assert( arr->length < size );
52 arr->elems[arr->length++] = x;
53}
54int find(array * arr, init_once * x) {
55 for (int i = 0; i < arr->length; i++) {
56 if ( arr->elems[i] == x ) {
57 return i;
58 }
59 }
60 return -1;
61}
62void ?{}(array * arr) {
63 memset(arr->elems, 0, sizeof(arr->elems));
64 arr->length = 0;
65}
66array constructed;
67array destructed;
68
69void ?{}(init_once * x) {
70 assert( find( &constructed, x ) == -1 );
71 remove( &destructed, x );
72 insert( &constructed, x );
73
74 x->x = malloc(sizeof(int));
75}
76
77void ?{}(init_once * x, init_once other) {
78 x{}; // reuse default ctor
79}
80
81void ^?{}(init_once * x) {
82 assert( find( &destructed, x ) == -1 );
83 remove( &constructed, x );
84 insert( &destructed, x );
85
86 free(x->x);
87}
88//*** end setup
89
90// test globals
91init_once x;
92init_once y = x;
93
94void static_variable() {
95 static init_once x;
96}
97
98int main() {
99 // local variables
100 init_once x;
101 init_once y = x;
102
103 // block scoped variables
104 {
105 init_once x;
106 init_once y = x;
107 }
108
109 // loop variables
110 for (int i = 0 ; i < 10; i++) {
111 init_once x;
112 init_once y = x;
113 }
114 int i = 0;
115 while (i < 10) {
116 init_once x;
117 init_once y = x;
118 i++;
119 }
120
121 // declared in a switch block with a break
122 for (int i = 0; i < 10; i++) {
123 switch (10) {
124 case 1: {
125 init_once x;
126 init_once y = x;
127 (&x) {}; // ensure this doesn't execute
128 break;
129 }
130 case 10: {
131 init_once x;
132 init_once y = x;
133 } // fall through
134 default: {
135 init_once x;
136 init_once y = x;
137 break;
138 }
139 }
140 }
141
142 // labeled break/continue
143 L3: for (int k = 0; k < 10; k++) {
144 init_once x;
145 init_once y = x;
146 L1: for (int i = 0; i < 10; i++){
147 init_once x;
148 init_once y = x;
149 L2: for (int j = 0; j < 10; j++) {
150 init_once x;
151 init_once y = x;
152
153 if (i == 0) continue L1;
154 if (i == 1) continue L2;
155 if (i == 2) break L2;
156 if (i == 3) break L1;
157 if (i == 4) continue L3;
158 if (i == 9) break L3;
159 // if (i == 5) goto ;
160 }
161 }
162 }
163
164 // labeled break/continue with if
165 LL1: for (int k = 0; k < 10; k++) {
166 init_once x;
167 init_once y = x;
168 LL2: for (int i = 0; i < 10; i++){
169 init_once x;
170 init_once y = x;
171 LL3: if( i < 5) {
172 init_once x;
173 init_once y = x;
174
175 if (i == 0) continue LL2;
176 if (i == 2) break LL3;
177 if (i == 3) break LL2;
178 if (i == 4) continue LL1;
179 } else {
180 if (i == 9) break LL1;
181 // if (i == 5) goto ;
182 }
183 }
184 }
185
186 // function-scoped static variable
187 for (int i = 0; i < 10; i++) {
188 static_variable();
189 }
190}
191
192// Local Variables: //
193// tab-width: 4 //
194// compile-command: "cfa init_once.c" //
195// End: //
Note: See TracBrowser for help on using the repository browser.