about summary refs log tree commit diff
diff options
context:
space:
mode:
authorklutzy <klutzytheklutzy@gmail.com>2014-05-10 17:30:55 +0900
committerAlex Crichton <alex@alexcrichton.com>2014-05-13 17:24:08 -0700
commit9f7caed2024268f6de16f99b6696d191f3ca3228 (patch)
tree19345dd5d3980348cc53e87b7f2a06af0f4ed768
parent6878039c122211f227d6c42b7f08282629ceb6c4 (diff)
downloadrust-9f7caed2024268f6de16f99b6696d191f3ca3228.tar.gz
rust-9f7caed2024268f6de16f99b6696d191f3ca3228.zip
rustllvm: Add LLVMRustArrayType
LLVM internally uses `uint64_t` for array size, but the corresponding
C API (`LLVMArrayType`) uses `unsigned int` so ths value is truncated.
Therefore rustc generates wrong type for fixed-sized large vector e.g.
`[0 x i8]` for `[0u8, ..(1 << 32)]`.

This patch adds `LLVMRustArrayType` function for `uint64_t` support.
-rw-r--r--src/librustc/lib/llvm.rs3
-rw-r--r--src/librustc/middle/trans/type_.rs2
-rw-r--r--src/rustllvm/RustWrapper.cpp6
-rw-r--r--src/test/run-pass/vec-fixed-length.rs14
4 files changed, 21 insertions, 4 deletions
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index e3d0e78e938..0c874bd776e 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -398,8 +398,7 @@ pub mod llvm {
         pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
 
         /* Operations on array, pointer, and vector types (sequence types) */
-        pub fn LLVMArrayType(ElementType: TypeRef, ElementCount: c_uint)
-                             -> TypeRef;
+        pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
         pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint)
                                -> TypeRef;
         pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint)
diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs
index a0744037dc0..d5a80edfaed 100644
--- a/src/librustc/middle/trans/type_.rs
+++ b/src/librustc/middle/trans/type_.rs
@@ -207,7 +207,7 @@ impl Type {
     }
 
     pub fn array(ty: &Type, len: u64) -> Type {
-        ty!(llvm::LLVMArrayType(ty.to_ref(), len as c_uint))
+        ty!(llvm::LLVMRustArrayType(ty.to_ref(), len))
     }
 
     pub fn vector(ty: &Type, len: u64) -> Type {
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index ec33b750358..717cd333a79 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -754,3 +754,9 @@ LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
     *ptr = ret.data();
     return ret.size();
 }
+
+// LLVMArrayType function does not support 64-bit ElementCount
+extern "C" LLVMTypeRef
+LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
+    return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
+}
diff --git a/src/test/run-pass/vec-fixed-length.rs b/src/test/run-pass/vec-fixed-length.rs
index 8e22be1b432..5116b4e746a 100644
--- a/src/test/run-pass/vec-fixed-length.rs
+++ b/src/test/run-pass/vec-fixed-length.rs
@@ -8,7 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::mem::size_of;
+
 pub fn main() {
     let x: [int, ..4] = [1, 2, 3, 4];
-    println!("{}", x[0]);
+    assert_eq!(x[0], 1);
+    assert_eq!(x[1], 2);
+    assert_eq!(x[2], 3);
+    assert_eq!(x[3], 4);
+
+    assert_eq!(size_of::<[u8, ..4]>(), 4u);
+
+    // FIXME #10183
+    if cfg!(target_word_size = "64") {
+        assert_eq!(size_of::<[u8, ..(1 << 32)]>(), (1u << 32));
+    }
 }