提交 cb1bec90 编写于 作者: J James Miller

Fix some type-related bugs

Some types weren't being properly monomorphised, and didn't have their
regions properly erased. This is now fixed.

Also fixes an issue where a temp was initialized in two separate
branches, but wasn't given an alloca.
上级 73790f02
......@@ -105,7 +105,9 @@ fn visit_lvalue(&mut self,
match *lvalue {
mir::Lvalue::Temp(index) => {
match context {
LvalueContext::Call |
LvalueContext::Call => {
self.mark_assigned(index as usize);
}
LvalueContext::Consume => {
}
LvalueContext::Store |
......
......@@ -16,7 +16,7 @@
use base;
use build;
use callee::{Callee, CalleeData, Fn, Intrinsic, NamedTupleConstructor, Virtual};
use common::{self, Block, BlockAndBuilder, C_undef};
use common::{self, type_is_fat_ptr, Block, BlockAndBuilder, C_undef};
use debuginfo::DebugLoc;
use Disr;
use machine::{llalign_of_min, llbitsize_of_real};
......@@ -169,6 +169,8 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
_ => bug!("{} is not callable", callee.ty)
};
let sig = bcx.tcx().erase_late_bound_regions(sig);
// Handle intrinsics old trans wants Expr's for, ourselves.
let intrinsic = match (&callee.ty.sty, &callee.data) {
(&ty::TyFnDef(def_id, _, _), &Intrinsic) => {
......@@ -200,7 +202,7 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
return;
}
let extra_args = &args[sig.0.inputs.len()..];
let extra_args = &args[sig.inputs.len()..];
let extra_args = extra_args.iter().map(|op_arg| {
self.mir.operand_ty(bcx.tcx(), op_arg)
}).collect::<Vec<_>>();
......@@ -263,30 +265,30 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
};
bcx.with_block(|bcx| {
let res = trans_intrinsic_call(bcx, callee.ty, &fn_ty,
trans_intrinsic_call(bcx, callee.ty, &fn_ty,
ArgVals(llargs), dest,
DebugLoc::None);
let bcx = res.bcx.build();
if let Some((_, target)) = *destination {
for op in args {
self.set_operand_dropped(&bcx, op);
}
funclet_br(bcx, self.llblock(target));
} else {
// trans_intrinsic_call already used Unreachable.
// bcx.unreachable();
}
});
if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
// Make a fake operand for store_return
let op = OperandRef {
val: OperandValue::Ref(dst),
ty: sig.0.output.unwrap()
ty: sig.output.unwrap()
};
self.store_return(&bcx, ret_dest, fn_ty.ret, op);
}
if let Some((_, target)) = *destination {
for op in args {
self.set_operand_dropped(&bcx, op);
}
funclet_br(bcx, self.llblock(target));
} else {
// trans_intrinsic_call already used Unreachable.
// bcx.unreachable();
}
return;
}
Fn(f) => f,
......@@ -318,7 +320,7 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
ret_bcx.at_start(|ret_bcx| {
let op = OperandRef {
val: OperandValue::Immediate(invokeret),
ty: sig.0.output.unwrap()
ty: sig.output.unwrap()
};
self.store_return(&ret_bcx, ret_dest, fn_ty.ret, op);
for op in args {
......@@ -332,7 +334,7 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
if let Some((_, target)) = *destination {
let op = OperandRef {
val: OperandValue::Immediate(llret),
ty: sig.0.output.unwrap()
ty: sig.output.unwrap()
};
self.store_return(&bcx, ret_dest, fn_ty.ret, op);
for op in args {
......@@ -554,6 +556,7 @@ fn make_return_dest(&mut self, bcx: &BlockAndBuilder<'bcx, 'tcx>,
let dest = match *dest {
mir::Lvalue::Temp(idx) => {
let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), dest);
let lvalue_ty = bcx.monomorphize(&lvalue_ty);
let ret_ty = lvalue_ty.to_ty(bcx.tcx());
match self.temps[idx as usize] {
TempRef::Lvalue(dest) => dest,
......@@ -633,6 +636,18 @@ fn store_return(&mut self,
self.temps[idx as usize] = TempRef::Operand(Some(op));
}
DirectOperand(idx) => {
let op = if type_is_fat_ptr(bcx.tcx(), op.ty) {
let llval = op.immediate();
let ptr = bcx.extract_value(llval, 0);
let meta = bcx.extract_value(llval, 1);
OperandRef {
val: OperandValue::FatPtr(ptr, meta),
ty: op.ty
}
} else {
op
};
self.temps[idx as usize] = TempRef::Operand(Some(op));
}
}
......
......@@ -220,6 +220,7 @@ pub fn with_lvalue_ref<F, U>(&mut self, bcx: &BlockAndBuilder<'bcx, 'tcx>,
TempRef::Lvalue(lvalue) => f(self, lvalue),
TempRef::Operand(None) => {
let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), lvalue);
let lvalue_ty = bcx.monomorphize(&lvalue_ty);
let lvalue = LvalueRef::alloca(bcx,
lvalue_ty.to_ty(bcx.tcx()),
"lvalue_temp");
......
......@@ -182,7 +182,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
debug!("type_of {:?}", t);
assert!(!t.has_escaping_regions());
assert!(!t.has_escaping_regions(), "{:?} has escaping regions", t);
// Replace any typedef'd types with their equivalent non-typedef
// type. This ensures that all LLVM nominal types that contain
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册