From 2a1786fdf9624ed6c15b69a36b622e3f7c5cd2b7 Mon Sep 17 00:00:00 2001 From: klutzy Date: Sat, 10 May 2014 17:30:55 +0900 Subject: [PATCH] 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. --- src/librustc/lib/llvm.rs | 3 +-- src/librustc/middle/trans/type_.rs | 2 +- src/rustllvm/RustWrapper.cpp | 6 ++++++ src/test/run-pass/vec-fixed-length.rs | 14 +++++++++++++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 74e332a8db456..d21157135581b 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 a0744037dc008..d5a80edfaedd1 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 ec33b750358bb..717cd333a79ce 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 8e22be1b4325c..5116b4e746a05 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)); + } }