diff options
| author | bors <bors@rust-lang.org> | 2013-06-04 02:10:33 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-06-04 02:10:33 -0700 |
| commit | b50030718cf28f2a5a81857a26b57442734fe854 (patch) | |
| tree | e13f9b1071d0c6a2fbebe162cc3b6ac93724e335 | |
| parent | 133d45171564c8b7de14523c9f3aa87140b9f043 (diff) | |
| parent | 0c9510ac389dc796e183e4125dbdd3a2e51b1f50 (diff) | |
| download | rust-b50030718cf28f2a5a81857a26b57442734fe854.tar.gz rust-b50030718cf28f2a5a81857a26b57442734fe854.zip | |
auto merge of #6927 : jld/rust/monomorphize-abi-alignment, r=sanxiyn
| -rw-r--r-- | src/librustc/middle/trans/monomorphize.rs | 8 | ||||
| -rw-r--r-- | src/test/run-pass/monomorphize-abi-alignment.rs | 31 |
2 files changed, 37 insertions, 2 deletions
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 7e29d3bd33a..062f72b6feb 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -30,7 +30,7 @@ use middle::trans::type_use; use middle::ty; use middle::ty::{FnSig}; use middle::typeck; -use util::ppaux::Repr; +use util::ppaux::{Repr,ty_to_str}; use core::vec; use syntax::ast; @@ -379,10 +379,14 @@ pub fn make_mono_id(ccx: @CrateContext, { let llty = type_of::type_of(ccx, subst); let size = machine::llbitsize_of_real(ccx, llty); - let align = machine::llalign_of_pref(ccx, llty); + let align = machine::llalign_of_min(ccx, llty); let mode = datum::appropriate_mode(subst); let data_class = mono_data_classify(subst); + debug!("make_mono_id: type %s -> size %u align %u mode %? class %?", + ty_to_str(ccx.tcx, subst), + size, align, mode, data_class); + // Special value for nil to prevent problems // with undef return pointers. if size <= 8u && ty::type_is_nil(subst) { diff --git a/src/test/run-pass/monomorphize-abi-alignment.rs b/src/test/run-pass/monomorphize-abi-alignment.rs new file mode 100644 index 00000000000..12c882a8708 --- /dev/null +++ b/src/test/run-pass/monomorphize-abi-alignment.rs @@ -0,0 +1,31 @@ +// Copyright 2013 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. + +/*! + * On x86_64-linux-gnu and possibly other platforms, structs get 8-byte "preferred" alignment, + * but their "ABI" alignment (i.e., what actually matters for data layout) is the largest alignment + * of any field. (Also, u64 has 8-byte ABI alignment; this is not always true). + * + * On such platforms, if monomorphize uses the "preferred" alignment, then it will unify + * `A` and `B`, even though `S<A>` and `S<B>` have the field `t` at different offsets, + * and apply the wrong instance of the method `unwrap`. + */ + +struct S<T> { i:u8, t:T } +impl<T> S<T> { fn unwrap(self) -> T { self.t } } +struct A((u32, u32)); +struct B(u64); + +pub fn main() { + static Ca: S<A> = S { i: 0, t: A((13, 104)) }; + static Cb: S<B> = S { i: 0, t: B(31337) }; + assert_eq!(*(Ca.unwrap()), (13, 104)); + assert_eq!(*(Cb.unwrap()), 31337); +} |
