Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve safety & usability of |size_t| and |ssize_t|. #28096

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiletest/raise_fd_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub unsafe fn raise_fd_limit() {
// Fetch the kern.maxfilesperproc value
let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC];
let mut maxfiles: libc::c_int = 0;
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
let mut size = size_of_val(&maxfiles);
if sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size,
null_mut(), 0) != 0 {
let err = io::Error::last_os_error();
Expand Down
10 changes: 5 additions & 5 deletions src/liballoc_jemalloc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,31 @@ fn align_to_flags(align: usize) -> c_int {
#[no_mangle]
pub extern fn __rust_allocate(size: usize, align: usize) -> *mut u8 {
let flags = align_to_flags(align);
unsafe { je_mallocx(size as size_t, flags) as *mut u8 }
unsafe { je_mallocx(size, flags) as *mut u8 }
}

#[no_mangle]
pub extern fn __rust_reallocate(ptr: *mut u8, _old_size: usize, size: usize,
align: usize) -> *mut u8 {
let flags = align_to_flags(align);
unsafe { je_rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8 }
unsafe { je_rallocx(ptr as *mut c_void, size, flags) as *mut u8 }
}

#[no_mangle]
pub extern fn __rust_reallocate_inplace(ptr: *mut u8, _old_size: usize,
size: usize, align: usize) -> usize {
let flags = align_to_flags(align);
unsafe { je_xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize }
unsafe { je_xallocx(ptr as *mut c_void, size, 0, flags) }
}

#[no_mangle]
pub extern fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize) {
let flags = align_to_flags(align);
unsafe { je_sdallocx(ptr as *mut c_void, old_size as size_t, flags) }
unsafe { je_sdallocx(ptr as *mut c_void, old_size, flags) }
}

#[no_mangle]
pub extern fn __rust_usable_size(size: usize, align: usize) -> usize {
let flags = align_to_flags(align);
unsafe { je_nallocx(size as size_t, flags) as usize }
unsafe { je_nallocx(size, flags) }
}
10 changes: 4 additions & 6 deletions src/liballoc_system/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,16 @@ mod imp {

pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
libc::malloc(size as libc::size_t) as *mut u8
libc::malloc(size) as *mut u8
} else {
#[cfg(target_os = "android")]
unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
memalign(align as libc::size_t, size as libc::size_t) as *mut u8
memalign(align, size) as *mut u8
}
#[cfg(not(target_os = "android"))]
unsafe fn more_aligned_malloc(size: usize, align: usize) -> *mut u8 {
let mut out = ptr::null_mut();
let ret = posix_memalign(&mut out,
align as libc::size_t,
size as libc::size_t);
let ret = posix_memalign(&mut out, align, size);
if ret != 0 {
ptr::null_mut()
} else {
Expand All @@ -110,7 +108,7 @@ mod imp {
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize,
align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
libc::realloc(ptr as *mut libc::c_void, size) as *mut u8
} else {
let new_ptr = allocate(size, align);
ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
Expand Down
8 changes: 2 additions & 6 deletions src/libflate/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Bytes {
unsafe {
let mut outsz: size_t = 0;
let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *const _,
bytes.len() as size_t,
&mut outsz,
flags);
bytes.len(), &mut outsz, flags);
assert!(!res.is_null());
Bytes {
ptr: Unique::new(res as *mut u8),
Expand All @@ -127,9 +125,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Result<Bytes,Error> {
unsafe {
let mut outsz: size_t = 0;
let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *const _,
bytes.len() as size_t,
&mut outsz,
flags);
bytes.len(), &mut outsz, flags);
if !res.is_null() {
Ok(Bytes {
ptr: Unique::new(res as *mut u8),
Expand Down
86 changes: 62 additions & 24 deletions src/liblibc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,50 @@ pub mod types {
}

// Standard types that are scalar but vary by OS and arch.
//
// ISO C's `size_t` is defined to be the type of the result of the
// `sizeof` operator and the type of the size parameter to `malloc`. That
// is, C's `size_t` is only required to hold the size of the largest object
// that can be allocated. In particular, it is legal for a C implementation
// to have a maximum object size smaller than the entire address space. For
// example, a C implementation may have an maximum object size of 2^32
// bytes with a 64-bit address space, and typedef `size_t` as `uint32_t` so
// that `sizeof(size_t) == 4` and `sizeof(void*) == 8`.
//
// Rust's `usize`, on the other hand, is defined to always be the same size
// as a pointer. This means that it is possible, in theory, to have a
// platform where `usize` can represent values that `size_t` cannot
// represent. However, on the vast majority of systems, `usize` and
// `size_t` are represented the same way. If it were required to explicitly
// cast `usize` to `size_t` on common platforms, then many programmers
// would habitually write expressions such as
// `my_slice.len() as libc::size_t` expecting this to always work and be
// safe. But such a cast is *not* safe on the uncommon platforms where
// `mem::sizeof(libc::size_t) < mem::size_t(usize)`. Consequently, to
// reduce the chances of programmers becoming habituated to such casts that
// would be unsafe on unusual platforms, we have adopted the following
// convention:
//
// * On common platforms where
// `mem::sizeof(libc::size_t) == mem::sizeof(usize)`, `libc::size_t` must
// be a type alias of `usize`, and `libc::ssize_t` must be a type alias
// of `isize`.
//
// * On uncommon platforms where
// `mem::sizeof(libc::size_t) != mem::sizeof(usize)`, `libc::size_t` and
// `libc::ssize_t` must be defined as types other than `usize` and
// `isize`.
//
// * Code that was written without consideration for the uncommon platforms
// should not do any explicit casting between `libc::size_t` and `usize`
// or `libc::ssize_t` and `isize`. Such code will fail to compile on the
// uncommon platforms; this is better than executing with unsafe
// truncations.
//
// * Code that was written with full consideration of the uncommon
// platforms should have explicit casts using `num::cast` or other
// methods that avoid unintended truncation. Such code will then work on
// all platforms.

#[cfg(any(target_os = "linux", target_os = "android", target_os = "nacl"))]
pub mod os {
Expand Down Expand Up @@ -429,7 +473,7 @@ pub mod types {
pub type c_ulong = u32;
pub type c_float = f32;
pub type c_double = f64;
pub type size_t = u32;
pub type size_t = usize;
pub type ptrdiff_t = i32;
pub type clock_t = i32;
pub type time_t = i32;
Expand Down Expand Up @@ -459,7 +503,7 @@ pub mod types {
pub type gid_t = u32;
pub type useconds_t = u32;
pub type mode_t = u32;
pub type ssize_t = i32;
pub type ssize_t = isize;
}
#[cfg(all(any(target_arch = "arm", target_arch = "x86"),
target_os = "android"))]
Expand All @@ -474,7 +518,7 @@ pub mod types {
pub type useconds_t = u32;

pub type mode_t = u16;
pub type ssize_t = i32;
pub type ssize_t = isize;
}
#[cfg(any(all(any(target_arch = "arm", target_arch = "x86"),
not(target_os = "android")),
Expand Down Expand Up @@ -655,7 +699,7 @@ pub mod types {
pub type c_ulong = u64;
pub type c_float = f32;
pub type c_double = f64;
pub type size_t = u64;
pub type size_t = usize;
pub type ptrdiff_t = i64;
pub type clock_t = i64;
pub type time_t = i64;
Expand All @@ -682,7 +726,7 @@ pub mod types {
pub type gid_t = u32;
pub type useconds_t = u32;
pub type mode_t = u32;
pub type ssize_t = i64;
pub type ssize_t = isize;
}
#[cfg(not(target_arch = "aarch64"))]
pub mod posix01 {
Expand Down Expand Up @@ -980,7 +1024,7 @@ pub mod types {
pub type c_ulong = u32;
pub type c_float = f32;
pub type c_double = f64;
pub type size_t = u32;
pub type size_t = usize;
pub type ptrdiff_t = i32;
pub type clock_t = i32;
pub type time_t = i32;
Expand All @@ -1004,7 +1048,7 @@ pub mod types {
pub type gid_t = u32;
pub type useconds_t = u32;
pub type mode_t = u16;
pub type ssize_t = i32;
pub type ssize_t = isize;
}
pub mod posix01 {
use types::common::c95::{c_void};
Expand Down Expand Up @@ -1074,7 +1118,7 @@ pub mod types {
pub type c_ulong = u64;
pub type c_float = f32;
pub type c_double = f64;
pub type size_t = u64;
pub type size_t = usize;
pub type ptrdiff_t = i64;
pub type clock_t = i32;
pub type time_t = i64;
Expand All @@ -1098,7 +1142,7 @@ pub mod types {
pub type gid_t = u32;
pub type useconds_t = u32;
pub type mode_t = u16;
pub type ssize_t = i64;
pub type ssize_t = isize;
}
pub mod posix01 {
use types::common::c95::{c_void};
Expand Down Expand Up @@ -1340,7 +1384,7 @@ pub mod types {
pub type c_ulong = u64;
pub type c_float = f32;
pub type c_double = f64;
pub type size_t = u64;
pub type size_t = usize;
pub type ptrdiff_t = i64;
pub type clock_t = i32;
pub type time_t = i64;
Expand All @@ -1363,7 +1407,7 @@ pub mod types {
pub type gid_t = u32;
pub type useconds_t = u32;
pub type mode_t = u16;
pub type ssize_t = i64;
pub type ssize_t = isize;
}
pub mod posix01 {
use types::common::c95::{c_void};
Expand Down Expand Up @@ -1625,7 +1669,7 @@ pub mod types {
pub type c_ulong = u64;
pub type c_float = f32;
pub type c_double = f64;
pub type size_t = u64;
pub type size_t = usize;
pub type ptrdiff_t = i64;
pub type clock_t = i64;
pub type time_t = i64;
Expand All @@ -1649,7 +1693,7 @@ pub mod types {
pub type gid_t = u32;
pub type useconds_t = u32;
pub type mode_t = u32;
pub type ssize_t = c_long;
pub type ssize_t = isize;
}
pub mod posix01 {
use types::common::c95::{c_void};
Expand Down Expand Up @@ -1845,10 +1889,7 @@ pub mod types {
pub type c_float = f32;
pub type c_double = f64;

#[cfg(target_arch = "x86")]
pub type size_t = u32;
#[cfg(target_arch = "x86_64")]
pub type size_t = u64;
pub type size_t = usize;

#[cfg(target_arch = "x86")]
pub type ptrdiff_t = i32;
Expand Down Expand Up @@ -1898,10 +1939,7 @@ pub mod types {
pub type useconds_t = u32;
pub type mode_t = u16;

#[cfg(target_arch = "x86")]
pub type ssize_t = i32;
#[cfg(target_arch = "x86_64")]
pub type ssize_t = i64;
pub type ssize_t = isize;
}

pub mod posix01 {
Expand Down Expand Up @@ -2345,7 +2383,7 @@ pub mod types {
pub type gid_t = u32;
pub type useconds_t = u32;
pub type mode_t = u16;
pub type ssize_t = c_long;
pub type ssize_t = isize;
}
pub mod posix01 {
use types::common::c99::{int32_t, int64_t, uint32_t};
Expand Down Expand Up @@ -2453,7 +2491,7 @@ pub mod types {
pub type gid_t = u32;
pub type useconds_t = u32;
pub type mode_t = u16;
pub type ssize_t = c_long;
pub type ssize_t = isize;
}
pub mod posix01 {
use types::common::c99::{int32_t, int64_t};
Expand Down Expand Up @@ -4711,7 +4749,7 @@ pub mod consts {

pub const PTHREAD_CREATE_JOINABLE : c_int = 0;
pub const PTHREAD_CREATE_DETACHED : c_int = 1;
pub const PTHREAD_STACK_MIN : size_t = 2048;
pub const PTHREAD_STACK_MIN: size_t = 2048;

pub const CLOCK_REALTIME : c_int = 0;
pub const CLOCK_MONOTONIC : c_int = 3;
Expand Down
11 changes: 3 additions & 8 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,14 +550,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
FfiSafe
}

ty::TyInt(ast::TyIs) => {
FfiUnsafe("found Rust type `isize` in foreign module, while \
`libc::c_int` or `libc::c_long` should be used")
}
ty::TyUint(ast::TyUs) => {
FfiUnsafe("found Rust type `usize` in foreign module, while \
`libc::c_uint` or `libc::c_ulong` should be used")
}
// FIXME: We should warn about `usize`/`isize`/ if (and only if)
// `size_t`/'ssize_t' are not defined as aliases for them.

ty::TyChar => {
FfiUnsafe("found Rust type `char` in foreign module, while \
`u32` or `libc::wchar_t` should be used")
Expand Down
4 changes: 1 addition & 3 deletions src/librustc_trans/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use std::path::{Path, PathBuf};
use std::process::{Command, Output, Stdio};
use std::str;

use libc;
use llvm::archive_ro::{ArchiveRO, Child};
use llvm::{self, ArchiveKind};
use rustc::metadata::loader::METADATA_FILENAME;
Expand Down Expand Up @@ -485,8 +484,7 @@ impl<'a> ArchiveBuilder<'a> {

let dst = self.config.dst.to_str().unwrap().as_bytes();
let dst = try!(CString::new(dst));
let r = llvm::LLVMRustWriteArchive(dst.as_ptr(),
members.len() as libc::size_t,
let r = llvm::LLVMRustWriteArchive(dst.as_ptr(), members.len(),
members.as_ptr(),
self.should_update_symbols,
kind);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
time(sess.time_passes(), &format!("ll link {}", name), || unsafe {
if !llvm::LLVMRustLinkInExternalBitcode(llmod,
ptr as *const libc::c_char,
bc_decoded.len() as libc::size_t) {
bc_decoded.len()) {
write::llvm_err(sess.diagnostic().handler(),
format!("failed to load bc of `{}`",
&name[..]));
Expand All @@ -115,7 +115,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
unsafe {
llvm::LLVMRustRunRestrictionPass(llmod,
ptr as *const *const libc::c_char,
arr.len() as libc::size_t);
arr.len());
}

if sess.no_landing_pads() {
Expand Down
Loading