@@ -137,7 +137,7 @@ impl BasicBlock {
137
137
if self . get_parent ( ) . is_none ( ) {
138
138
return None ;
139
139
}
140
-
140
+
141
141
let bb = unsafe {
142
142
LLVMGetNextBasicBlock ( self . basic_block )
143
143
} ;
@@ -146,6 +146,7 @@ impl BasicBlock {
146
146
}
147
147
148
148
/// Prepends one `BasicBlock` before another.
149
+ /// It returns `Err(())` when either `BasicBlock` has no parent, as LLVM assumes it has a parent.
149
150
///
150
151
/// # Example
151
152
/// ```no_run
@@ -168,13 +169,21 @@ impl BasicBlock {
168
169
/// assert_eq!(basic_block2.get_next_basic_block().unwrap(), basic_block1);
169
170
/// ```
170
171
// REVIEW: What happens if blocks are from different scopes?
171
- pub fn move_before ( & self , basic_block : & BasicBlock ) {
172
+ pub fn move_before ( & self , basic_block : & BasicBlock ) -> Result < ( ) , ( ) > {
173
+ // This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
174
+ if self . get_parent ( ) . is_none ( ) || basic_block. get_parent ( ) . is_none ( ) {
175
+ return Err ( ( ) ) ;
176
+ }
177
+
172
178
unsafe {
173
179
LLVMMoveBasicBlockBefore ( self . basic_block , basic_block. basic_block )
174
180
}
181
+
182
+ Ok ( ( ) )
175
183
}
176
184
177
185
/// Appends one `BasicBlock` after another.
186
+ /// It returns `Err(())` when either `BasicBlock` has no parent, as LLVM assumes it has a parent.
178
187
///
179
188
/// # Example
180
189
/// ```no_run
@@ -197,10 +206,17 @@ impl BasicBlock {
197
206
/// assert_eq!(basic_block2.get_next_basic_block().unwrap(), basic_block1);
198
207
/// ```
199
208
// REVIEW: What happens if blocks are from different scopes?
200
- pub fn move_after ( & self , basic_block : & BasicBlock ) {
209
+ pub fn move_after ( & self , basic_block : & BasicBlock ) -> Result < ( ) , ( ) > {
210
+ // This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
211
+ if self . get_parent ( ) . is_none ( ) || basic_block. get_parent ( ) . is_none ( ) {
212
+ return Err ( ( ) ) ;
213
+ }
214
+
201
215
unsafe {
202
216
LLVMMoveBasicBlockAfter ( self . basic_block , basic_block. basic_block )
203
217
}
218
+
219
+ Ok ( ( ) )
204
220
}
205
221
206
222
/// Prepends a new `BasicBlock` before this one.
@@ -340,6 +356,7 @@ impl BasicBlock {
340
356
}
341
357
342
358
/// Removes this `BasicBlock` from its parent `FunctionValue`. Does nothing if it has no parent.
359
+ /// It returns `Err(())` when it has no parent to remove from, as LLVM assumes it has a parent.
343
360
///
344
361
/// # Example
345
362
/// ```no_run
@@ -364,16 +381,21 @@ impl BasicBlock {
364
381
// by taking ownership of self (though BasicBlock's are not uniquely obtained...)
365
382
// might have to make some methods do something like -> Result<..., BasicBlock<Orphan>> for BasicBlock<HasParent>
366
383
// and would move_before/after make it no longer orphaned? etc..
367
- pub fn remove_from_function ( & self ) {
384
+ pub fn remove_from_function ( & self ) -> Result < ( ) , ( ) > {
368
385
// This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
369
- if self . get_parent ( ) . is_some ( ) {
370
- unsafe {
371
- LLVMRemoveBasicBlockFromParent ( self . basic_block )
372
- }
386
+ if self . get_parent ( ) . is_none ( ) {
387
+ return Err ( ( ) ) ;
373
388
}
389
+
390
+ unsafe {
391
+ LLVMRemoveBasicBlockFromParent ( self . basic_block )
392
+ }
393
+
394
+ Ok ( ( ) )
374
395
}
375
396
376
397
/// Removes this `BasicBlock` completely from memory. This is unsafe because you could easily have other references to the same `BasicBlock`.
398
+ /// It returns `Err(())` when it has no parent to delete from, as LLVM assumes it has a parent.
377
399
///
378
400
/// # Example
379
401
/// ```no_run
@@ -393,11 +415,15 @@ impl BasicBlock {
393
415
/// }
394
416
/// assert!(function.get_basic_blocks().is_empty());
395
417
/// ```
396
- // REVIEW: Could potentially be unsafe if there are existing references. Might need a global ref counter
397
- pub unsafe fn delete ( self ) {
398
- // unsafe {
399
- LLVMDeleteBasicBlock ( self . basic_block )
400
- // }
418
+ pub unsafe fn delete ( self ) -> Result < ( ) , ( ) > {
419
+ // This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
420
+ if self . get_parent ( ) . is_none ( ) {
421
+ return Err ( ( ) ) ;
422
+ }
423
+
424
+ LLVMDeleteBasicBlock ( self . basic_block ) ;
425
+
426
+ Ok ( ( ) )
401
427
}
402
428
403
429
/// Obtains the `ContextRef` this `BasicBlock` belongs to.
0 commit comments