diff --git a/src/librustc_trans/trans/mir/operand.rs b/src/librustc_trans/trans/mir/operand.rs index 6240473b78ec3..114e78b05bddd 100644 --- a/src/librustc_trans/trans/mir/operand.rs +++ b/src/librustc_trans/trans/mir/operand.rs @@ -169,6 +169,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { 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), diff --git a/src/librustc_trans/trans/mir/rvalue.rs b/src/librustc_trans/trans/mir/rvalue.rs index b57d3b107fb45..f0842554277cc 100644 --- a/src/librustc_trans/trans/mir/rvalue.rs +++ b/src/librustc_trans/trans/mir/rvalue.rs @@ -108,11 +108,15 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { }, _ => { 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); + } } } } diff --git a/src/test/codegen/mir_zst_stores.rs b/src/test/codegen/mir_zst_stores.rs new file mode 100644 index 0000000000000..c1acdaf703191 --- /dev/null +++ b/src/test/codegen/mir_zst_stores.rs @@ -0,0 +1,27 @@ +// 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 or the MIT license +// , 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 } + +// CHECK-LABEL: @mir +#[no_mangle] +#[rustc_mir] +fn mir(){ + // CHECK-NOT: getelementptr + // CHECK-NOT: store{{.*}}undef + let x = Zst { phantom: PhantomData }; +}