@@ -12,7 +12,7 @@ use crate::basic_block::BasicBlock;
12
12
use crate :: values:: { AggregateValue , AggregateValueEnum , AsValueRef , BasicValue , BasicValueEnum , PhiValue , FunctionValue , IntValue , PointerValue , VectorValue , InstructionValue , GlobalValue , IntMathValue , FloatMathValue , PointerMathValue , InstructionOpcode , CallSiteValue } ;
13
13
#[ llvm_versions( 3.9 ..=latest) ]
14
14
use crate :: values:: StructValue ;
15
- use crate :: types:: { AsTypeRef , BasicType , IntMathType , FloatMathType , PointerType , PointerMathType } ;
15
+ use crate :: types:: { AsTypeRef , BasicType , BasicTypeEnum , IntMathType , FloatMathType , PointerType , PointerMathType } ;
16
16
17
17
use std:: ffi:: CString ;
18
18
use std:: marker:: PhantomData ;
@@ -348,25 +348,56 @@ impl<'ctx> Builder<'ctx> {
348
348
}
349
349
350
350
// TODOC: Heap allocation
351
- pub fn build_malloc < T : BasicType < ' ctx > > ( & self , ty : T , name : & str ) -> PointerValue < ' ctx > {
351
+ pub fn build_malloc < T : BasicType < ' ctx > > ( & self , ty : T , name : & str ) -> Result < PointerValue < ' ctx > , & ' static str > {
352
+ // LLVMBulidMalloc segfaults if ty is unsized
353
+ let is_sized = match ty. as_basic_type_enum ( ) {
354
+ BasicTypeEnum :: ArrayType ( ty) => ty. is_sized ( ) ,
355
+ BasicTypeEnum :: FloatType ( ty) => ty. is_sized ( ) ,
356
+ BasicTypeEnum :: IntType ( ty) => ty. is_sized ( ) ,
357
+ BasicTypeEnum :: PointerType ( ty) => ty. is_sized ( ) ,
358
+ BasicTypeEnum :: StructType ( ty) => ty. is_sized ( ) ,
359
+ BasicTypeEnum :: VectorType ( ty) => ty. is_sized ( ) ,
360
+ } ;
361
+ if !is_sized {
362
+ return Err ( "Cannot build malloc call for an unsized type" ) ;
363
+ }
364
+
352
365
let c_string = CString :: new ( name) . expect ( "Conversion to CString failed unexpectedly" ) ;
353
366
354
367
let value = unsafe {
355
368
LLVMBuildMalloc ( self . builder , ty. as_type_ref ( ) , c_string. as_ptr ( ) )
356
369
} ;
357
370
358
- PointerValue :: new ( value)
371
+ Ok ( PointerValue :: new ( value) )
359
372
}
360
373
361
374
// TODOC: Heap allocation
362
- pub fn build_array_malloc < T : BasicType < ' ctx > > ( & self , ty : T , size : IntValue < ' ctx > , name : & str ) -> PointerValue < ' ctx > {
375
+ pub fn build_array_malloc < T : BasicType < ' ctx > > (
376
+ & self ,
377
+ ty : T ,
378
+ size : IntValue < ' ctx > ,
379
+ name : & str
380
+ ) -> Result < PointerValue < ' ctx > , & ' static str > {
381
+ // LLVMBulidArrayMalloc segfaults if ty is unsized
382
+ let is_sized = match ty. as_basic_type_enum ( ) {
383
+ BasicTypeEnum :: ArrayType ( ty) => ty. is_sized ( ) ,
384
+ BasicTypeEnum :: FloatType ( ty) => ty. is_sized ( ) ,
385
+ BasicTypeEnum :: IntType ( ty) => ty. is_sized ( ) ,
386
+ BasicTypeEnum :: PointerType ( ty) => ty. is_sized ( ) ,
387
+ BasicTypeEnum :: StructType ( ty) => ty. is_sized ( ) ,
388
+ BasicTypeEnum :: VectorType ( ty) => ty. is_sized ( ) ,
389
+ } ;
390
+ if !is_sized {
391
+ return Err ( "Cannot build array malloc call for an unsized type" ) ;
392
+ }
393
+
363
394
let c_string = CString :: new ( name) . expect ( "Conversion to CString failed unexpectedly" ) ;
364
395
365
396
let value = unsafe {
366
397
LLVMBuildArrayMalloc ( self . builder , ty. as_type_ref ( ) , size. as_value_ref ( ) , c_string. as_ptr ( ) )
367
398
} ;
368
399
369
- PointerValue :: new ( value)
400
+ Ok ( PointerValue :: new ( value) )
370
401
}
371
402
372
403
// SubType: <P>(&self, ptr: PointerValue<P>) -> InstructionValue {
0 commit comments