operand: OperandRef<'tcx>)
{
debug!("store_operand: operand={}", operand.repr(bcx));
+ // Avoid generating stores of zero-sized values, because the only way to have a zero-sized
+ // value is through `undef`, and store itself is useless.
+ if common::type_is_zero_size(bcx.ccx(), operand.ty) {
+ return;
+ }
match operand.val {
OperandValue::Ref(r) => base::memcpy_ty(bcx, lldest, r, operand.ty),
OperandValue::Immediate(s) => base::store_ty(bcx, s, lldest, operand.ty),
},
_ => {
for (i, operand) in operands.iter().enumerate() {
- // Note: perhaps this should be StructGep, but
- // note that in some cases the values here will
- // not be structs but arrays.
- let lldest_i = build::GEPi(bcx, dest.llval, &[0, i]);
- self.trans_operand_into(bcx, lldest_i, operand);
+ let op = self.trans_operand(bcx, operand);
+ // Do not generate stores and GEPis for zero-sized fields.
+ if !common::type_is_zero_size(bcx.ccx(), op.ty) {
+ // Note: perhaps this should be StructGep, but
+ // note that in some cases the values here will
+ // not be structs but arrays.
+ let dest = build::GEPi(bcx, dest.llval, &[0, i]);
+ self.store_operand(bcx, dest, op);
+ }
}
}
}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: -C no-prepopulate-passes
+
+#![feature(rustc_attrs)]
+#![crate_type = "lib"]
+use std::marker::PhantomData;
+
+
+struct Zst { phantom: PhantomData<Zst> }
+
+// CHECK-LABEL: @mir
+#[no_mangle]
+#[rustc_mir]
+fn mir(){
+ // CHECK-NOT: getelementptr
+ // CHECK-NOT: store{{.*}}undef
+ let x = Zst { phantom: PhantomData };
+}