]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #18728: thestinger/int
authorJakub Bukaj <jakub@jakub.cc>
Wed, 19 Nov 2014 21:36:59 +0000 (22:36 +0100)
committerJakub Bukaj <jakub@jakub.cc>
Wed, 19 Nov 2014 21:36:59 +0000 (22:36 +0100)
This fixes the gap in the language definition causing #18726 by defining
a clear bound on the maximum size for libraries to enforce.

Closes #18069

1  2 
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/context.rs
src/librustc_trans/trans/type_of.rs

index c5f66cf0c542ffbda014fa31bbf649ecb305d271,5ef78c1475bf50c9f6b45d5f332503769040f223..2e184a5d74b7309b9e2557fab378f215540ca7ee
@@@ -469,13 -458,13 +469,13 @@@ pub fn ty_of_inttype<'tcx>(ity: IntType
  }
  
  // LLVM doesn't like types that don't fit in the address space
 -fn ensure_struct_fits_in_address_space(ccx: &CrateContext,
 -                                       fields: &[Type],
 -                                       packed: bool,
 -                                       scapegoat: ty::t) {
 +fn ensure_struct_fits_in_address_space<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 +                                                 fields: &[Type],
 +                                                 packed: bool,
 +                                                 scapegoat: Ty<'tcx>) {
      let mut offset = 0;
      for &llty in fields.iter() {
-         // Invariant: offset < ccx.max_obj_size() <= 1<<61
+         // Invariant: offset < ccx.obj_size_bound() <= 1<<61
          if !packed {
              let type_align = machine::llalign_of_min(ccx, llty);
              offset = roundup(offset, type_align);
index 4822299d1488614336f4b54eb77cacb52a31d522,c0066ff4d81e1324505487d90066e320770ad917..6a28ef38c519aea76529a3a090e6486749e9334d
@@@ -705,11 -703,26 +705,26 @@@ impl<'b, 'tcx> CrateContext<'b, 'tcx> 
          &self.local.trait_cache
      }
  
-     pub fn max_obj_size(&self) -> u64 {
-         1<<31 /* FIXME #18069: select based on architecture */
+     /// Return exclusive upper bound on object size.
+     ///
+     /// The theoretical maximum object size is defined as the maximum positive `int` value. This
+     /// ensures that the `offset` semantics remain well-defined by allowing it to correctly index
+     /// every address within an object along with one byte past the end, along with allowing `int`
+     /// to store the difference between any two pointers into an object.
+     ///
+     /// The upper bound on 64-bit currently needs to be lower because LLVM uses a 64-bit integer to
+     /// represent object size in bits. It would need to be 1 << 61 to account for this, but is
+     /// currently conservatively bounded to 1 << 47 as that is enough to cover the current usable
+     /// address space on 64-bit ARMv8 and x86_64.
+     pub fn obj_size_bound(&self) -> u64 {
+         match self.sess().target.target.target_word_size[] {
+             "32" => 1 << 31,
+             "64" => 1 << 47,
+             _ => unreachable!() // error handled by config::build_target_config
+         }
      }
  
 -    pub fn report_overbig_object(&self, obj: ty::t) -> ! {
 +    pub fn report_overbig_object(&self, obj: Ty<'tcx>) -> ! {
          self.sess().fatal(
              format!("the type `{}` is too big for the current architecture",
                      obj.repr(self.tcx())).as_slice())
index 31e8130dd751334b982bd9e786239af68cbc8b56,6bba40ccc7a718840b351e7456cf099c153b2d4b..005f6ca4c7086bc92cbf9abc26df53a51a2382e1
@@@ -28,13 -28,13 +28,13 @@@ use syntax::abi
  use syntax::ast;
  
  // LLVM doesn't like objects that are too big. Issue #17913
 -fn ensure_array_fits_in_address_space(ccx: &CrateContext,
 -                                      llet: Type,
 -                                      size: machine::llsize,
 -                                      scapegoat: ty::t) {
 +fn ensure_array_fits_in_address_space<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 +                                                llet: Type,
 +                                                size: machine::llsize,
 +                                                scapegoat: Ty<'tcx>) {
      let esz = machine::llsize_of_alloc(ccx, llet);
      match esz.checked_mul(size) {
-         Some(n) if n < ccx.max_obj_size() => {}
+         Some(n) if n < ccx.obj_size_bound() => {}
          _ => { ccx.report_overbig_object(scapegoat) }
      }
  }