Skip to content

Commit 7bd6f5c

Browse files
pnkfelixbrson
authored andcommitted
Inject bitcast if types mismatch when building a store instruction.
1 parent 2fbf70b commit 7bd6f5c

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/librustc_trans/builder.rs

+24
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
543543
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
544544
assert!(!self.llbuilder.is_null());
545545
self.count_insn("store");
546+
let ptr = self.check_store(val, ptr);
546547
unsafe {
547548
llvm::LLVMBuildStore(self.llbuilder, val, ptr)
548549
}
@@ -552,6 +553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
552553
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
553554
assert!(!self.llbuilder.is_null());
554555
self.count_insn("store.volatile");
556+
let ptr = self.check_store(val, ptr);
555557
unsafe {
556558
let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
557559
llvm::LLVMSetVolatile(insn, llvm::True);
@@ -562,6 +564,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
562564
pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) {
563565
debug!("Store {:?} -> {:?}", Value(val), Value(ptr));
564566
self.count_insn("store.atomic");
567+
let ptr = self.check_store(val, ptr);
565568
unsafe {
566569
let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
567570
let align = llalign_of_pref(self.ccx, ty.element_type());
@@ -1100,6 +1103,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11001103
}
11011104
}
11021105

1106+
/// Returns the ptr value that should be used for storing `val`.
1107+
fn check_store<'b>(&self,
1108+
val: ValueRef,
1109+
ptr: ValueRef) -> ValueRef {
1110+
let dest_ptr_ty = val_ty(ptr);
1111+
let stored_ty = val_ty(val);
1112+
let stored_ptr_ty = stored_ty.ptr_to();
1113+
1114+
assert_eq!(dest_ptr_ty.kind(), llvm::TypeKind::Pointer);
1115+
1116+
if dest_ptr_ty == stored_ptr_ty {
1117+
ptr
1118+
} else {
1119+
debug!("Type mismatch in store. \
1120+
Expected {:?}, got {:?}; inserting bitcast",
1121+
dest_ptr_ty, stored_ptr_ty);
1122+
self.bitcast(ptr, stored_ptr_ty)
1123+
}
1124+
}
1125+
1126+
/// Returns the args that should be used for a call to `llfn`.
11031127
fn check_call<'b>(&self,
11041128
typ: &str,
11051129
llfn: ValueRef,

0 commit comments

Comments
 (0)