source: src/tests/init_once.c @ 026a0f5

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 026a0f5 was 72e9222, checked in by Rob Schluntz <rschlunt@…>, 8 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.