diff options
| author | Corey Richardson <corey@octayn.net> | 2014-05-26 23:56:52 -0700 |
|---|---|---|
| committer | Corey Richardson <corey@octayn.net> | 2014-08-20 21:02:23 -0400 |
| commit | 6e8ff999589a7b4c7f62f7128f3e028a7b3ea64f (patch) | |
| tree | 71eb65a9aefa3503f15b4bd8245f36081f658c27 | |
| parent | 54bd9e6323742de87a526931a15558319db30604 (diff) | |
| download | rust-6e8ff999589a7b4c7f62f7128f3e028a7b3ea64f.tar.gz rust-6e8ff999589a7b4c7f62f7128f3e028a7b3ea64f.zip | |
librustc: handle repr on structs, require it for ffi, unify with packed
As of RFC 18, struct layout is undefined. Opting into a C-compatible struct layout is now down with #[repr(C)]. For consistency, specifying a packed layout is now also down with #[repr(packed)]. Both can be specified. To fix errors caused by this, just add #[repr(C)] to the structs, and change #[packed] to #[repr(packed)] Closes #14309 [breaking-change]
27 files changed, 210 insertions, 118 deletions
diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 9c699a88007..874c7c2409c 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -334,6 +334,7 @@ pub mod types { __variant1, __variant2, } + pub enum FILE {} pub enum fpos_t {} } diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 7e0ba613e3d..ec25c27539b 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -27,7 +27,6 @@ use metadata::csearch; use middle::def::*; -use middle::trans::adt; // for `adt::is_ffi_safe` use middle::typeck::astconv::ast_ty_to_ty; use middle::typeck::infer; use middle::{typeck, ty, def, pat_util, stability}; @@ -362,8 +361,13 @@ impl LintPass for CTypes { "found rust type `uint` in foreign module, while \ libc::c_uint or libc::c_ulong should be used"); } - def::DefTy(def_id) => { - if !adt::is_ffi_safe(cx.tcx, def_id) { + def::DefTy(..) => { + let tty = match cx.tcx.ast_ty_to_ty_cache.borrow().find(&ty.id) { + Some(&ty::atttce_resolved(t)) => t, + _ => fail!("ast_ty_to_ty_cache was incomplete after typeck!") + }; + + if !ty::is_ffi_safe(cx.tcx, tty) { cx.span_lint(CTYPES, ty.span, "found enum type without foreign-function-safe representation annotation in foreign module, consider \ @@ -770,9 +774,10 @@ impl LintPass for NonCamelCaseTypes { } } - let has_extern_repr = it.attrs.iter().fold(attr::ReprAny, |acc, attr| { - attr::find_repr_attr(cx.tcx.sess.diagnostic(), attr, acc) - }) == attr::ReprExtern; + let has_extern_repr = it.attrs.iter().map(|attr| { + attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr).iter() + .any(|r| r == &attr::ReprExtern) + }).any(|x| x); if has_extern_repr { return } match it.node { @@ -783,6 +788,7 @@ impl LintPass for NonCamelCaseTypes { check_case(cx, "trait", it.ident, it.span) } ast::ItemEnum(ref enum_definition, _) => { + if has_extern_repr { return } check_case(cx, "type", it.ident, it.span); for variant in enum_definition.variants.iter() { check_case(cx, "variant", variant.node.name, variant.span); diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 9a7bfb0e6dc..0dfdf455743 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -195,9 +195,10 @@ impl<'a> MarkSymbolVisitor<'a> { ast_map::NodeItem(item) => { match item.node { ast::ItemStruct(..) => { - let has_extern_repr = item.attrs.iter().fold(attr::ReprAny, |acc, attr| { - attr::find_repr_attr(self.tcx.sess.diagnostic(), attr, acc) - }) == attr::ReprExtern; + let has_extern_repr = item.attrs.iter().fold(false, |acc, attr| { + acc || attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr) + .iter().any(|&x| x == attr::ReprExtern) + }); visit::walk_item(self, &*item, MarkSymbolVisitorContext { struct_has_extern_repr: has_extern_repr, diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 9c68631baa4..483937edd9f 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -46,6 +46,8 @@ #![allow(unsigned_negate)] use libc::c_ulonglong; +use std::collections::Map; +use std::num::Int; use std::rc::Rc; use llvm::{ValueRef, True, IntEQ, IntNE}; @@ -178,7 +180,8 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr { } ty::ty_enum(def_id, ref substs) => { let cases = get_cases(cx.tcx(), def_id, substs); - let hint = ty::lookup_repr_hint(cx.tcx(), def_id); + let hint = *ty::lookup_repr_hints(cx.tcx(), def_id).as_slice().get(0) + .unwrap_or(&attr::ReprAny); let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag(); @@ -266,36 +269,6 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr { } } -/// Determine, without doing translation, whether an ADT must be FFI-safe. -/// For use in lint or similar, where being sound but slightly incomplete is acceptable. -pub fn is_ffi_safe(tcx: &ty::ctxt, def_id: ast::DefId) -> bool { - match ty::get(ty::lookup_item_type(tcx, def_id).ty).sty { - ty::ty_enum(def_id, _) => { - let variants = ty::enum_variants(tcx, def_id); - // Univariant => like struct/tuple. - if variants.len() <= 1 { - return true; - } - let hint = ty::lookup_repr_hint(tcx, def_id); - // Appropriate representation explicitly selected? - if hint.is_ffi_safe() { - return true; - } - // Option<Box<T>> and similar are used in FFI. Rather than try to - // resolve type parameters and recognize this case exactly, this - // overapproximates -- assuming that if a non-C-like enum is being - // used in FFI then the user knows what they're doing. - if variants.iter().any(|vi| !vi.args.is_empty()) { - return true; - } - false - } - // struct, tuple, etc. - // (is this right in the present of typedefs?) - _ => true - } -} - // this should probably all be in ty struct Case { discr: Disr, @@ -427,6 +400,9 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp } attr::ReprAny => { attempts = choose_shortest; + }, + attr::ReprPacked => { + cx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum"); } } for &ity in attempts.iter() { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index ae96937757f..83eb84a326a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -481,7 +481,7 @@ pub struct t { inner: *const t_opaque } impl fmt::Show for t { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - "*t_opaque".fmt(f) + write!(f, "{}", get(*self)) } } @@ -1962,7 +1962,8 @@ def_type_content_sets!( // ReachesManaged /* see [1] below */ = 0b0000_0100__0000_0000__0000, ReachesMutable = 0b0000_1000__0000_0000__0000, ReachesNoSync = 0b0001_0000__0000_0000__0000, - ReachesAll = 0b0001_1111__0000_0000__0000, + ReachesFfiUnsafe = 0b0010_0000__0000_0000__0000, + ReachesAll = 0b0011_1111__0000_0000__0000, // Things that cause values to *move* rather than *copy* Moves = 0b0000_0000__0000_1011__0000, @@ -2199,6 +2200,11 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { cache.insert(ty_id, TC::None); let result = match get(ty).sty { + // uint and int are ffi-unsafe + ty_uint(ast::TyU) | ty_int(ast::TyI) => { + TC::ReachesFfiUnsafe + } + // Scalar and unique types are sendable, and durable ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | ty_bare_fn(_) | ty::ty_char | ty_str => { @@ -2206,22 +2212,22 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { } ty_closure(ref c) => { - closure_contents(cx, &**c) + closure_contents(cx, &**c) | TC::ReachesFfiUnsafe } ty_box(typ) => { - tc_ty(cx, typ, cache).managed_pointer() + tc_ty(cx, typ, cache).managed_pointer() | TC::ReachesFfiUnsafe } ty_uniq(typ) => { - match get(typ).sty { + TC::ReachesFfiUnsafe | match get(typ).sty { ty_str => TC::OwnsOwned, _ => tc_ty(cx, typ, cache).owned_pointer(), } } ty_trait(box ty::TyTrait { bounds, .. }) => { - object_contents(cx, bounds) + object_contents(cx, bounds) | TC::ReachesFfiUnsafe } ty_ptr(ref mt) => { @@ -2229,8 +2235,9 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { } ty_rptr(r, ref mt) => { - match get(mt.ty).sty { + TC::ReachesFfiUnsafe | match get(mt.ty).sty { ty_str => borrowed_contents(r, ast::MutImmutable), + ty_vec(..) => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(r, mt.mutbl)), _ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(r, mt.mutbl)), } } @@ -2244,6 +2251,11 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { let mut res = TypeContents::union(flds.as_slice(), |f| tc_mt(cx, f.mt, cache)); + + if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) { + res = res | TC::ReachesFfiUnsafe; + } + if ty::has_dtor(cx, did) { res = res | TC::OwnsDtor; } @@ -2273,9 +2285,49 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { tc_ty(cx, *arg_ty, cache) }) }); + if ty::has_dtor(cx, did) { res = res | TC::OwnsDtor; } + + if variants.len() != 0 { + let repr_hints = lookup_repr_hints(cx, did); + if repr_hints.len() > 1 { + // this is an error later on, but this type isn't safe + res = res | TC::ReachesFfiUnsafe; + } + + match repr_hints.as_slice().get(0) { + Some(h) => if !h.is_ffi_safe() { + res = res | TC::ReachesFfiUnsafe; + }, + // ReprAny + None => { + res = res | TC::ReachesFfiUnsafe; + + // We allow ReprAny enums if they are eligible for + // the nullable pointer optimization and the + // contained type is an `extern fn` + + if variants.len() == 2 { + let mut data_idx = 0; + + if variants.get(0).args.len() == 0 { + data_idx = 1; + } + + if variants.get(data_idx).args.len() == 1 { + match get(*variants.get(data_idx).args.get(0)).sty { + ty_bare_fn(..) => { res = res - TC::ReachesFfiUnsafe; } + _ => { } + } + } + } + } + } + } + + apply_lang_items(cx, did, res) } @@ -2427,6 +2479,10 @@ pub fn type_moves_by_default(cx: &ctxt, ty: t) -> bool { type_contents(cx, ty).moves_by_default(cx) } +pub fn is_ffi_safe(cx: &ctxt, ty: t) -> bool { + !type_contents(cx, ty).intersects(TC::ReachesFfiUnsafe) +} + // True if instantiating an instance of `r_ty` requires an instance of `r_ty`. pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool { fn type_requires(cx: &ctxt, seen: &mut Vec<DefId>, @@ -3945,7 +4001,7 @@ pub fn substd_enum_variants(cx: &ctxt, -> Vec<Rc<VariantInfo>> { enum_variants(cx, id).iter().map(|variant_info| { let substd_args = variant_info.args.iter() - .map(|aty| aty.subst(cx, substs)).collect(); + .map(|aty| aty.subst(cx, substs)).collect::<Vec<_>>(); let substd_ctor_ty = variant_info.ctor_ty.subst(cx, substs); @@ -4168,9 +4224,9 @@ pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool { found } -/// Determine whether an item is annotated with `#[packed]` +/// Determine whether an item is annotated with `#[repr(packed)]` pub fn lookup_packed(tcx: &ctxt, did: DefId) -> bool { - has_attr(tcx, did, "packed") + lookup_repr_hints(tcx, did).contains(&attr::ReprPacked) } /// Determine whether an item is annotated with `#[simd]` @@ -4178,14 +4234,16 @@ pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool { has_attr(tcx, did, "simd") } -// Obtain the representation annotation for a definition. -pub fn lookup_repr_hint(tcx: &ctxt, did: DefId) -> attr::ReprAttr { - let mut acc = attr::ReprAny; +/// Obtain the representation annotation for a struct definition. +pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Vec<attr::ReprAttr> { + let mut acc = Vec::new(); + ty::each_attr(tcx, did, |meta| { - acc = attr::find_repr_attr(tcx.sess.diagnostic(), meta, acc); + acc.extend(attr::find_repr_attrs(tcx.sess.diagnostic(), meta).move_iter()); true }); - return acc; + + acc } // Look up a field ID, whether or not it's local diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 1cec680ff2c..5f89a1f48bd 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -4180,13 +4180,13 @@ pub fn check_enum_variants(ccx: &CrateCtxt, let inh = blank_inherited_fields(ccx); let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id); let declty = match hint { - attr::ReprAny | attr::ReprExtern => ty::mk_int(), + attr::ReprAny | attr::ReprPacked | attr::ReprExtern => ty::mk_int(), attr::ReprInt(_, attr::SignedInt(ity)) => { ty::mk_mach_int(ity) } attr::ReprInt(_, attr::UnsignedInt(ity)) => { ty::mk_mach_uint(ity) - } + }, }; check_const_with_ty(&fcx, e.span, &*e, declty); // check_expr (from check_const pass) doesn't guarantee @@ -4225,6 +4225,9 @@ pub fn check_enum_variants(ccx: &CrateCtxt, "discriminant type specified here"); } } + attr::ReprPacked => { + ccx.tcx.sess.bug("range_to_inttype: found ReprPacked on an enum"); + } } disr_vals.push(current_disr_val); @@ -4238,7 +4241,9 @@ pub fn check_enum_variants(ccx: &CrateCtxt, return variants; } - let hint = ty::lookup_repr_hint(ccx.tcx, ast::DefId { krate: ast::LOCAL_CRATE, node: id }); + let hint = *ty::lookup_repr_hints(ccx.tcx, ast::DefId { krate: ast::LOCAL_CRATE, node: id }) + .as_slice().get(0).unwrap_or(&attr::ReprAny); + if hint != attr::ReprAny && vs.len() <= 1 { if vs.len() == 1 { span_err!(ccx.tcx.sess, sp, E0083, diff --git a/src/librustrt/libunwind.rs b/src/librustrt/libunwind.rs index 72d78d84aa3..8d2305a8a80 100644 --- a/src/librustrt/libunwind.rs +++ b/src/librustrt/libunwind.rs @@ -72,6 +72,7 @@ pub static unwinder_private_data_size: uint = 5; #[cfg(target_arch = "mipsel")] pub static unwinder_private_data_size: uint = 2; +#[repr(C)] pub struct _Unwind_Exception { pub exception_class: _Unwind_Exception_Class, pub exception_cleanup: _Unwind_Exception_Cleanup_Fn, diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs index a4491b2ab1d..5ef1286500c 100644 --- a/src/libstd/rt/backtrace.rs +++ b/src/libstd/rt/backtrace.rs @@ -701,7 +701,7 @@ mod imp { static IMAGE_FILE_MACHINE_IA64: libc::DWORD = 0x0200; static IMAGE_FILE_MACHINE_AMD64: libc::DWORD = 0x8664; - #[packed] + #[repr(packed)] struct SYMBOL_INFO { SizeOfStruct: libc::c_ulong, TypeIndex: libc::c_ulong, diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 21252619d11..4b2a3073755 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -418,19 +418,14 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[Gc<MetaItem>]) { } -/// Fold this over attributes to parse #[repr(...)] forms. +/// Parse #[repr(...)] forms. /// /// Valid repr contents: any of the primitive integral type names (see -/// `int_type_of_word`, below) to specify the discriminant type; and `C`, to use -/// the same discriminant size that the corresponding C enum would. These are -/// not allowed on univariant or zero-variant enums, which have no discriminant. -/// -/// If a discriminant type is so specified, then the discriminant will be -/// present (before fields, if any) with that type; representation -/// optimizations which would remove it will not be done. -pub fn find_repr_attr(diagnostic: &SpanHandler, attr: &Attribute, acc: ReprAttr) - -> ReprAttr { - let mut acc = acc; +/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use +/// the same discriminant size that the corresponding C enum would or C +/// structure layout, and `packed` to remove padding. +pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAttr> { + let mut acc = Vec::new(); match attr.node.value.node { ast::MetaList(ref s, ref items) if s.equiv(&("repr")) => { mark_used(attr); @@ -439,28 +434,26 @@ pub fn find_repr_attr(diagnostic: &SpanHandler, attr: &Attribute, acc: ReprAttr) ast::MetaWord(ref word) => { let hint = match word.get() { // Can't use "extern" because it's not a lexical identifier. - "C" => ReprExtern, + "C" => Some(ReprExtern), + "packed" => Some(ReprPacked), _ => match int_type_of_word(word.get()) { - Some(ity) => ReprInt(item.span, ity), + Some(ity) => Some(ReprInt(item.span, ity)), None => { // Not a word we recognize diagnostic.span_err(item.span, "unrecognized representation hint"); - ReprAny + None } } }; - if hint != ReprAny { - if acc == ReprAny { - acc = hint; - } else if acc != hint { - diagnostic.span_warn(item.span, - "conflicting representation hint ignored") - } + + match hint { + Some(h) => acc.push(h), + None => { } } } // Not a word: - _ => diagnostic.span_err(item.span, "unrecognized representation hint") + _ => diagnostic.span_err(item.span, "unrecognized enum representation hint") } } } @@ -490,7 +483,8 @@ fn int_type_of_word(s: &str) -> Option<IntType> { pub enum ReprAttr { ReprAny, ReprInt(Span, IntType), - ReprExtern + ReprExtern, + ReprPacked, } impl ReprAttr { @@ -498,7 +492,8 @@ impl ReprAttr { match *self { ReprAny => false, ReprInt(_sp, ity) => ity.is_ffi_safe(), - ReprExtern => true + ReprExtern => true, + ReprPacked => false } } } @@ -523,7 +518,7 @@ impl IntType { SignedInt(ast::TyI16) | UnsignedInt(ast::TyU16) | SignedInt(ast::TyI32) | UnsignedInt(ast::TyU32) | SignedInt(ast::TyI64) | UnsignedInt(ast::TyU64) => true, - _ => false + SignedInt(ast::TyI) | UnsignedInt(ast::TyU) => false } } } diff --git a/src/test/auxiliary/packed.rs b/src/test/auxiliary/packed.rs index 54b2658e380..86f5f93e3cf 100644 --- a/src/test/auxiliary/packed.rs +++ b/src/test/auxiliary/packed.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[packed] +#[repr(packed)] pub struct S { a: u8, b: u32 diff --git a/src/test/compile-fail/issue-14309.rs b/src/test/compile-fail/issue-14309.rs new file mode 100644 index 00000000000..eb8e75eae78 --- /dev/null +++ b/src/test/compile-fail/issue-14309.rs @@ -0,0 +1,49 @@ +// Copyright 2014 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. + +#![deny(ctypes)] +#![allow(dead_code)] + +struct A { //~ NOTE consider adding `#[repr(C)]` to this type + x: int +} + +#[repr(C, packed)] +struct B { + x: int, + y: A +} + +#[repr(C)] +struct C { + x: int +} + +type A2 = A; +type B2 = B; +type C2 = C; + +#[repr(C)] +struct D { + x: C, + y: A +} + +extern "C" { + fn foo(x: A); //~ ERROR found struct without FFI-safe representation used in FFI + fn bar(x: B); //~ ERROR FFI-safe + fn baz(x: C); + fn qux(x: A2); //~ ERROR FFI-safe + fn quux(x: B2); //~ ERROR FFI-safe + fn corge(x: C2); + fn fred(x: D); //~ ERROR FFI-safe +} + +fn main() { } diff --git a/src/test/compile-fail/lint-ctypes-enum.rs b/src/test/compile-fail/lint-ctypes-enum.rs index e968bd601c5..d597006e29d 100644 --- a/src/test/compile-fail/lint-ctypes-enum.rs +++ b/src/test/compile-fail/lint-ctypes-enum.rs @@ -19,8 +19,8 @@ enum T { E, F, G } extern { fn zf(x: Z); fn uf(x: U); - fn bf(x: B); //~ ERROR found enum type without foreign-function-safe - fn tf(x: T); //~ ERROR found enum type without foreign-function-safe + fn bf(x: B); //~ ERROR found enum without FFI-safe + fn tf(x: T); //~ ERROR found enum without FFI-safe } pub fn main() { } diff --git a/src/test/compile-fail/packed-struct-generic-transmute.rs b/src/test/compile-fail/packed-struct-generic-transmute.rs index b5bb3314dcf..7a1ff574488 100644 --- a/src/test/compile-fail/packed-struct-generic-transmute.rs +++ b/src/test/compile-fail/packed-struct-generic-transmute.rs @@ -19,7 +19,7 @@ extern crate debug; use std::mem; -#[packed] +#[repr(packed)] struct Foo<T,S> { bar: T, baz: S diff --git a/src/test/compile-fail/packed-struct-transmute.rs b/src/test/compile-fail/packed-struct-transmute.rs index 0611c470d10..f92cc4b1344 100644 --- a/src/test/compile-fail/packed-struct-transmute.rs +++ b/src/test/compile-fail/packed-struct-transmute.rs @@ -19,7 +19,7 @@ extern crate debug; use std::mem; -#[packed] +#[repr(packed)] struct Foo { bar: u8, baz: uint diff --git a/src/test/debuginfo/c-style-enum-in-composite.rs b/src/test/debuginfo/c-style-enum-in-composite.rs index f7351728290..ef23e7ee876 100644 --- a/src/test/debuginfo/c-style-enum-in-composite.rs +++ b/src/test/debuginfo/c-style-enum-in-composite.rs @@ -87,7 +87,7 @@ struct PaddedStruct { e: i16 } -#[packed] +#[repr(packed)] struct PackedStruct { a: i16, b: AnEnum, diff --git a/src/test/debuginfo/packed-struct-with-destructor.rs b/src/test/debuginfo/packed-struct-with-destructor.rs index 215d961b71b..00a560edbf0 100644 --- a/src/test/debuginfo/packed-struct-with-destructor.rs +++ b/src/test/debuginfo/packed-struct-with-destructor.rs @@ -77,7 +77,7 @@ #![allow(unused_variable)] -#[packed] +#[repr(packed)] struct Packed { x: i16, y: i32, @@ -88,7 +88,7 @@ impl Drop for Packed { fn drop(&mut self) {} } -#[packed] +#[repr(packed)] struct PackedInPacked { a: i32, b: Packed, @@ -113,7 +113,7 @@ impl Drop for Unpacked { fn drop(&mut self) {} } -#[packed] +#[repr(packed)] struct UnpackedInPacked { a: i16, b: Unpacked, @@ -121,7 +121,7 @@ struct UnpackedInPacked { d: i64 } -#[packed] +#[repr(packed)] struct PackedInPackedWithDrop { a: i32, b: Packed, @@ -144,7 +144,7 @@ impl Drop for PackedInUnpackedWithDrop { fn drop(&mut self) {} } -#[packed] +#[repr(packed)] struct UnpackedInPackedWithDrop { a: i16, b: Unpacked, diff --git a/src/test/debuginfo/packed-struct.rs b/src/test/debuginfo/packed-struct.rs index 8201afe3a01..bf2213509cf 100644 --- a/src/test/debuginfo/packed-struct.rs +++ b/src/test/debuginfo/packed-struct.rs @@ -63,14 +63,14 @@ #![allow(unused_variable)] -#[packed] +#[repr(packed)] struct Packed { x: i16, y: i32, z: i64 } -#[packed] +#[repr(packed)] struct PackedInPacked { a: i32, b: Packed, @@ -95,7 +95,7 @@ struct Unpacked { } // layout (64 bit): aabb bbbb bbbb bbbb bbbb bbbb bbcc cccc cccc cccc cccc cccc ccdd dddd dd -#[packed] +#[repr(packed)] struct UnpackedInPacked { a: i16, b: Unpacked, diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.rs b/src/test/run-make/extern-fn-with-packed-struct/test.rs index 4b07b7f39f5..8d8daed1393 100644 --- a/src/test/run-make/extern-fn-with-packed-struct/test.rs +++ b/src/test/run-make/extern-fn-with-packed-struct/test.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[packed] +#[repr(packed)] #[deriving(PartialEq, Show)] struct Foo { a: i8, diff --git a/src/test/run-pass/packed-struct-borrow-element.rs b/src/test/run-pass/packed-struct-borrow-element.rs index 1434e1da4c7..c6c74fe3fda 100644 --- a/src/test/run-pass/packed-struct-borrow-element.rs +++ b/src/test/run-pass/packed-struct-borrow-element.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[packed] +#[repr(packed)] struct Foo { bar: u8, baz: uint diff --git a/src/test/run-pass/packed-struct-generic-layout.rs b/src/test/run-pass/packed-struct-generic-layout.rs index 20269766158..999e4aeeb59 100644 --- a/src/test/run-pass/packed-struct-generic-layout.rs +++ b/src/test/run-pass/packed-struct-generic-layout.rs @@ -10,7 +10,7 @@ use std::mem; -#[packed] +#[repr(packed)] struct S<T, S> { a: T, b: u8, diff --git a/src/test/run-pass/packed-struct-generic-size.rs b/src/test/run-pass/packed-struct-generic-size.rs index 80f37a0fa3d..45791332bbe 100644 --- a/src/test/run-pass/packed-struct-generic-size.rs +++ b/src/test/run-pass/packed-struct-generic-size.rs @@ -10,7 +10,7 @@ use std::mem; -#[packed] +#[repr(packed)] struct S<T, S> { a: T, b: u8, diff --git a/src/test/run-pass/packed-struct-layout.rs b/src/test/run-pass/packed-struct-layout.rs index 7f9bf8e7d57..b4fbf0820cd 100644 --- a/src/test/run-pass/packed-struct-layout.rs +++ b/src/test/run-pass/packed-struct-layout.rs @@ -10,13 +10,13 @@ use std::mem; -#[packed] +#[repr(packed)] struct S4 { a: u8, b: [u8, .. 3], } -#[packed] +#[repr(packed)] struct S5 { a: u8, b: u32 diff --git a/src/test/run-pass/packed-struct-match.rs b/src/test/run-pass/packed-struct-match.rs index 27ab2c83e55..46ffed0cba9 100644 --- a/src/test/run-pass/packed-struct-match.rs +++ b/src/test/run-pass/packed-struct-match.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[packed] +#[repr(packed)] struct Foo { bar: u8, baz: uint diff --git a/src/test/run-pass/packed-struct-size.rs b/src/test/run-pass/packed-struct-size.rs index 8dbc7cf327d..cfea444d7ff 100644 --- a/src/test/run-pass/packed-struct-size.rs +++ b/src/test/run-pass/packed-struct-size.rs @@ -12,19 +12,19 @@ use std::mem; use std::gc::Gc; -#[packed] +#[repr(packed)] struct S4 { a: u8, b: [u8, .. 3], } -#[packed] +#[repr(packed)] struct S5 { a: u8, b: u32 } -#[packed] +#[repr(packed)] struct S13 { a: i64, b: f32, @@ -36,14 +36,14 @@ enum Foo { Baz = 2 } -#[packed] +#[repr(packed)] struct S3_Foo { a: u8, b: u16, c: Foo } -#[packed] +#[repr(packed)] struct S7_Option { a: f32, b: u8, diff --git a/src/test/run-pass/packed-struct-vec.rs b/src/test/run-pass/packed-struct-vec.rs index 8309e95820c..c20e62351a6 100644 --- a/src/test/run-pass/packed-struct-vec.rs +++ b/src/test/run-pass/packed-struct-vec.rs @@ -12,7 +12,7 @@ use std::mem; -#[packed] +#[repr(packed)] #[deriving(PartialEq, Show)] struct Foo { bar: u8, diff --git a/src/test/run-pass/packed-tuple-struct-layout.rs b/src/test/run-pass/packed-tuple-struct-layout.rs index 3ec6182beb2..5fb43503ccb 100644 --- a/src/test/run-pass/packed-tuple-struct-layout.rs +++ b/src/test/run-pass/packed-tuple-struct-layout.rs @@ -10,10 +10,10 @@ use std::mem; -#[packed] +#[repr(packed)] struct S4(u8,[u8, .. 3]); -#[packed] +#[repr(packed)] struct S5(u8,u32); pub fn main() { diff --git a/src/test/run-pass/packed-tuple-struct-size.rs b/src/test/run-pass/packed-tuple-struct-size.rs index da6e9a9dac0..f23166288fb 100644 --- a/src/test/run-pass/packed-tuple-struct-size.rs +++ b/src/test/run-pass/packed-tuple-struct-size.rs @@ -12,13 +12,13 @@ use std::gc::Gc; use std::mem; -#[packed] +#[repr(packed)] struct S4(u8,[u8, .. 3]); -#[packed] +#[repr(packed)] struct S5(u8, u32); -#[packed] +#[repr(packed)] struct S13(i64, f32, u8); enum Foo { @@ -26,10 +26,10 @@ enum Foo { Baz = 2 } -#[packed] +#[repr(packed)] struct S3_Foo(u8, u16, Foo); -#[packed] +#[repr(packed)] struct S7_Option(f32, u8, u16, Option<Gc<f64>>); pub fn main() { |
