File tree Expand file tree Collapse file tree 1 file changed +49
-0
lines changed Expand file tree Collapse file tree 1 file changed +49
-0
lines changed Original file line number Diff line number Diff line change @@ -149,6 +149,55 @@ class KnownSizeSet {
149
149
size_t size () const { return numElements; }
150
150
};
151
151
152
+ // / Embed a reference to a Bitfield container inside a longer-lived object so
153
+ // / the bitfield container can be stack allocated with a properly nested minimal
154
+ // / lifetime. Accessing the container outside the scope of it's stack allocation
155
+ // / results in a nullptr dereference.
156
+ // /
157
+ // / struct Parent {
158
+ // / BitfieldRef<Container> container;
159
+ // /
160
+ // / void performWithContainer(SILFunction *function) {
161
+ // / BitfieldRef<Container>::StackState state(container, functon);
162
+ // /
163
+ // / assert(container->isValid());
164
+ // / }
165
+ // / };
166
+ // /
167
+ // / TODO: give this variadic template parameters to support a BitfieldContainer
168
+ // / whose constructor takes more than a single SILFunction argument.
169
+ template <typename BitfieldContainer> struct BitfieldRef {
170
+ BitfieldContainer *ref = nullptr ;
171
+
172
+ BitfieldRef () {}
173
+
174
+ BitfieldContainer &operator *() const {
175
+ assert (ref);
176
+ return *ref;
177
+ }
178
+
179
+ BitfieldContainer *operator ->() const {
180
+ assert (ref);
181
+ return ref;
182
+ }
183
+
184
+ // Stack-allocated state must be nested relative to other node bitfields.
185
+ struct StackState {
186
+ BitfieldRef &ref;
187
+ BitfieldContainer container;
188
+
189
+ StackState (BitfieldRef &ref, SILFunction *function)
190
+ : ref(ref), container(function) {
191
+ ref.ref = &container;
192
+ }
193
+
194
+ ~StackState () { ref.ref = nullptr ; }
195
+ };
196
+
197
+ private:
198
+ BitfieldRef (const BitfieldRef &) = delete ;
199
+ };
200
+
152
201
} // namespace swift
153
202
154
203
#endif
You can’t perform that action at this time.
0 commit comments