@@ -22,6 +22,7 @@ use value::Value;
2222use util:: nodemap:: FnvHashMap ;
2323use libc:: { c_uint, c_char} ;
2424
25+ use std:: borrow:: Cow ;
2526use std:: ffi:: CString ;
2627use std:: ptr;
2728use syntax_pos:: Span ;
@@ -175,8 +176,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
175176 . collect:: <Vec <String >>( )
176177 . join( ", " ) ) ;
177178
178- check_call ( "invoke" , llfn, args) ;
179-
179+ let args = self . check_call ( "invoke" , llfn, args) ;
180180 let bundle = bundle. as_ref ( ) . map ( |b| b. raw ( ) ) . unwrap_or ( ptr:: null_mut ( ) ) ;
181181
182182 unsafe {
@@ -857,8 +857,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
857857 . collect:: <Vec <String >>( )
858858 . join( ", " ) ) ;
859859
860- check_call ( "call" , llfn, args) ;
861-
860+ let args = self . check_call ( "call" , llfn, args) ;
862861 let bundle = bundle. as_ref ( ) . map ( |b| b. raw ( ) ) . unwrap_or ( ptr:: null_mut ( ) ) ;
863862
864863 unsafe {
@@ -1100,10 +1099,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11001099 llvm:: LLVMRustBuildAtomicFence ( self . llbuilder , order, scope) ;
11011100 }
11021101 }
1103- }
11041102
1105- fn check_call ( typ : & str , llfn : ValueRef , args : & [ ValueRef ] ) {
1106- if cfg ! ( debug_assertions) {
1103+ fn check_call < ' b > ( & self ,
1104+ typ : & str ,
1105+ llfn : ValueRef ,
1106+ args : & ' b [ ValueRef ] ) -> Cow < ' b , [ ValueRef ] > {
11071107 let mut fn_ty = val_ty ( llfn) ;
11081108 // Strip off pointers
11091109 while fn_ty. kind ( ) == llvm:: TypeKind :: Pointer {
@@ -1115,16 +1115,31 @@ fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) {
11151115
11161116 let param_tys = fn_ty. func_params ( ) ;
11171117
1118- let iter = param_tys. into_iter ( )
1119- . zip ( args. iter ( ) . map ( |& v| val_ty ( v) ) ) ;
1120- for ( i, ( expected_ty, actual_ty) ) in iter. enumerate ( ) {
1121- if expected_ty != actual_ty {
1122- bug ! ( "Type mismatch in function call of {:?}. \
1123- Expected {:?} for param {}, got {:?}",
1124- Value ( llfn) ,
1125- expected_ty, i, actual_ty) ;
1118+ let all_args_match = param_tys. iter ( )
1119+ . zip ( args. iter ( ) . map ( |& v| val_ty ( v) ) )
1120+ . all ( |( expected_ty, actual_ty) | * expected_ty == actual_ty) ;
1121+
1122+ if all_args_match {
1123+ return Cow :: Borrowed ( args) ;
1124+ }
1125+
1126+ let casted_args: Vec < _ > = param_tys. into_iter ( )
1127+ . zip ( args. iter ( ) )
1128+ . enumerate ( )
1129+ . map ( |( i, ( expected_ty, & actual_val) ) | {
1130+ let actual_ty = val_ty ( actual_val) ;
1131+ if expected_ty != actual_ty {
1132+ debug ! ( "Type mismatch in function call of {:?}. \
1133+ Expected {:?} for param {}, got {:?}; injecting bitcast",
1134+ Value ( llfn) ,
1135+ expected_ty, i, actual_ty) ;
1136+ self . bitcast ( actual_val, expected_ty)
1137+ } else {
1138+ actual_val
1139+ }
1140+ } )
1141+ . collect ( ) ;
11261142
1127- }
1128- }
1143+ return Cow :: Owned ( casted_args) ;
11291144 }
11301145}
0 commit comments