提交 97e41435 编写于 作者: F Felix S. Klock II

Fix ICE by injecting bitcasts if types mismatch when building invokes or calls.

上级 a29c49f5
......@@ -22,6 +22,7 @@
use util::nodemap::FnvHashMap;
use libc::{c_uint, c_char};
use std::borrow::Cow;
use std::ffi::CString;
use std::ptr;
use syntax_pos::Span;
......@@ -175,8 +176,7 @@ pub fn invoke(&self,
.collect::<Vec<String>>()
.join(", "));
check_call("invoke", llfn, args);
let args = self.check_call("invoke", llfn, args);
let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut());
unsafe {
......@@ -857,8 +857,7 @@ pub fn call(&self, llfn: ValueRef, args: &[ValueRef],
.collect::<Vec<String>>()
.join(", "));
check_call("call", llfn, args);
let args = self.check_call("call", llfn, args);
let bundle = bundle.as_ref().map(|b| b.raw()).unwrap_or(ptr::null_mut());
unsafe {
......@@ -1100,10 +1099,11 @@ pub fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope) {
llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope);
}
}
}
fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) {
if cfg!(debug_assertions) {
fn check_call<'b>(&self,
typ: &str,
llfn: ValueRef,
args: &'b [ValueRef]) -> Cow<'b, [ValueRef]> {
let mut fn_ty = val_ty(llfn);
// Strip off pointers
while fn_ty.kind() == llvm::TypeKind::Pointer {
......@@ -1115,16 +1115,31 @@ fn check_call(typ: &str, llfn: ValueRef, args: &[ValueRef]) {
let param_tys = fn_ty.func_params();
let iter = param_tys.into_iter()
.zip(args.iter().map(|&v| val_ty(v)));
for (i, (expected_ty, actual_ty)) in iter.enumerate() {
if expected_ty != actual_ty {
bug!("Type mismatch in function call of {:?}. \
Expected {:?} for param {}, got {:?}",
Value(llfn),
expected_ty, i, actual_ty);
let all_args_match = param_tys.iter()
.zip(args.iter().map(|&v| val_ty(v)))
.all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
if all_args_match {
return Cow::Borrowed(args);
}
let casted_args: Vec<_> = param_tys.into_iter()
.zip(args.iter())
.enumerate()
.map(|(i, (expected_ty, &actual_val))| {
let actual_ty = val_ty(actual_val);
if expected_ty != actual_ty {
debug!("Type mismatch in function call of {:?}. \
Expected {:?} for param {}, got {:?}; injecting bitcast",
Value(llfn),
expected_ty, i, actual_ty);
self.bitcast(actual_val, expected_ty)
} else {
actual_val
}
})
.collect();
}
}
return Cow::Owned(casted_args);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册