From c7669dff2af371338004cb92cd7d757bc2961d21 Mon Sep 17 00:00:00 2001 From: Irina Popa Date: Tue, 17 Jul 2018 15:02:11 +0300 Subject: [PATCH] rustc_codegen_llvm: use safe references for ArchiveChild. --- src/librustc_codegen_llvm/back/archive.rs | 6 +-- src/librustc_codegen_llvm/llvm/archive_ro.rs | 39 ++++++---------- src/librustc_codegen_llvm/llvm/ffi.rs | 49 ++++++++++++++++---- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index 4ea97911830c..d290753a5bc2 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -14,7 +14,7 @@ use std::ffi::{CString, CStr}; use std::io; use std::mem; use std::path::{Path, PathBuf}; -use std::ptr::{self, NonNull}; +use std::ptr; use std::str; use back::bytecode::RLIB_BYTECODE_EXTENSION; @@ -246,7 +246,7 @@ impl<'a> ArchiveBuilder<'a> { let name = CString::new(child_name)?; members.push(llvm::LLVMRustArchiveMemberNew(ptr::null(), name.as_ptr(), - NonNull::new(child.raw()))); + Some(child.raw))); strings.push(name); } } @@ -284,7 +284,7 @@ impl<'a> ArchiveBuilder<'a> { let name = CString::new(child_name)?; let m = llvm::LLVMRustArchiveMemberNew(ptr::null(), name.as_ptr(), - NonNull::new(child.raw())); + Some(child.raw)); members.push(m); strings.push(name); } diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs index 1d215910d955..324d52bbef4b 100644 --- a/src/librustc_codegen_llvm/llvm/archive_ro.rs +++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs @@ -11,24 +11,22 @@ //! A wrapper around LLVM's archive (.a) code use std::ffi::CString; -use std::marker; use std::path::Path; use std::slice; use std::str; pub struct ArchiveRO { - raw: &'static mut super::Archive, + pub raw: &'static mut super::Archive, } unsafe impl Send for ArchiveRO {} pub struct Iter<'a> { - ptr: &'a mut super::ArchiveIterator<'a>, + raw: &'a mut super::ArchiveIterator<'a>, } pub struct Child<'a> { - ptr: super::ArchiveChildRef, - _data: marker::PhantomData<&'a ArchiveRO>, + pub raw: &'a mut super::ArchiveChild<'a>, } impl ArchiveRO { @@ -59,14 +57,10 @@ impl ArchiveRO { } } - pub fn raw(&self) -> &super::Archive { - self.raw - } - pub fn iter(&self) -> Iter { unsafe { Iter { - ptr: super::LLVMRustArchiveIteratorNew(self.raw), + raw: super::LLVMRustArchiveIteratorNew(self.raw), } } } @@ -84,14 +78,11 @@ impl<'a> Iterator for Iter<'a> { type Item = Result, String>; fn next(&mut self) -> Option, String>> { - let ptr = unsafe { super::LLVMRustArchiveIteratorNext(self.ptr) }; - if ptr.is_null() { - super::last_error().map(Err) - } else { - Some(Ok(Child { - ptr, - _data: marker::PhantomData, - })) + unsafe { + match super::LLVMRustArchiveIteratorNext(self.raw) { + Some(raw) => Some(Ok(Child { raw })), + None => super::last_error().map(Err), + } } } } @@ -99,7 +90,7 @@ impl<'a> Iterator for Iter<'a> { impl<'a> Drop for Iter<'a> { fn drop(&mut self) { unsafe { - super::LLVMRustArchiveIteratorFree(&mut *(self.ptr as *mut _)); + super::LLVMRustArchiveIteratorFree(&mut *(self.raw as *mut _)); } } } @@ -108,7 +99,7 @@ impl<'a> Child<'a> { pub fn name(&self) -> Option<&'a str> { unsafe { let mut name_len = 0; - let name_ptr = super::LLVMRustArchiveChildName(self.ptr, &mut name_len); + let name_ptr = super::LLVMRustArchiveChildName(self.raw, &mut name_len); if name_ptr.is_null() { None } else { @@ -121,23 +112,19 @@ impl<'a> Child<'a> { pub fn data(&self) -> &'a [u8] { unsafe { let mut data_len = 0; - let data_ptr = super::LLVMRustArchiveChildData(self.ptr, &mut data_len); + let data_ptr = super::LLVMRustArchiveChildData(self.raw, &mut data_len); if data_ptr.is_null() { panic!("failed to read data from archive child"); } slice::from_raw_parts(data_ptr as *const u8, data_len as usize) } } - - pub fn raw(&self) -> super::ArchiveChildRef { - self.ptr - } } impl<'a> Drop for Child<'a> { fn drop(&mut self) { unsafe { - super::LLVMRustArchiveChildFree(self.ptr); + super::LLVMRustArchiveChildFree(&mut *(self.raw as *mut _)); } } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 2dda2dd00d2f..c139868544df 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -25,7 +25,6 @@ use libc::{c_uint, c_int, size_t, c_char}; use libc::{c_ulonglong, c_void}; use std::marker::PhantomData; -use std::ptr::NonNull; use super::RustString; @@ -383,6 +382,7 @@ pub enum ThreadLocalMode { } extern { type Opaque; } +#[repr(C)] struct InvariantOpaque<'a> { _marker: PhantomData<&'a mut &'a ()>, _opaque: Opaque, @@ -397,22 +397,27 @@ extern { pub type Metadata; } extern { pub type BasicBlock; } extern { pub type Builder; } extern { pub type MemoryBuffer; } +#[repr(C)] pub struct PassManager<'a>(InvariantOpaque<'a>); extern { pub type PassManagerBuilder; } extern { pub type ObjectFile; } +#[repr(C)] pub struct SectionIterator<'a>(InvariantOpaque<'a>); extern { pub type Pass; } extern { pub type TargetMachine; } extern { pub type Archive; } +#[repr(C)] pub struct ArchiveIterator<'a>(InvariantOpaque<'a>); -extern { pub type ArchiveChild; } -pub type ArchiveChildRef = *mut ArchiveChild; +#[repr(C)] +pub struct ArchiveChild<'a>(InvariantOpaque<'a>); extern { pub type Twine; } extern { pub type DiagnosticInfo; } extern { pub type SMDiagnostic; } extern { pub type RustArchiveMember; } pub type RustArchiveMemberRef = *mut RustArchiveMember; +#[repr(C)] pub struct OperandBundleDef<'a>(InvariantOpaque<'a>); +#[repr(C)] pub struct Linker<'a>(InvariantOpaque<'a>); pub type DiagnosticHandler = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); @@ -474,7 +479,6 @@ pub mod debuginfo { extern { pub type ModuleBuffer; } -#[allow(improper_ctypes)] // TODO remove this (use for NonNull) extern "C" { // Create and destroy contexts. pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context; @@ -1403,10 +1407,15 @@ extern "C" { -> &'a Value; pub fn LLVMRustDIBuilderCreateOpDeref() -> i64; pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64; +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustWriteTypeToString(Type: &Type, s: &RustString); pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); +} +extern "C" { pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>; @@ -1471,21 +1480,29 @@ extern "C" { pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>; pub fn LLVMRustArchiveIteratorNew(AR: &'a Archive) -> &'a mut ArchiveIterator<'a>; - pub fn LLVMRustArchiveIteratorNext(AIR: &ArchiveIterator) -> ArchiveChildRef; - pub fn LLVMRustArchiveChildName(ACR: ArchiveChildRef, size: &mut size_t) -> *const c_char; - pub fn LLVMRustArchiveChildData(ACR: ArchiveChildRef, size: &mut size_t) -> *const c_char; - pub fn LLVMRustArchiveChildFree(ACR: ArchiveChildRef); + pub fn LLVMRustArchiveIteratorNext(AIR: &ArchiveIterator<'a>) -> Option<&'a mut ArchiveChild<'a>>; + pub fn LLVMRustArchiveChildName(ACR: &ArchiveChild, size: &mut size_t) -> *const c_char; + pub fn LLVMRustArchiveChildData(ACR: &ArchiveChild, size: &mut size_t) -> *const c_char; + pub fn LLVMRustArchiveChildFree(ACR: &'a mut ArchiveChild<'a>); pub fn LLVMRustArchiveIteratorFree(AIR: &'a mut ArchiveIterator<'a>); pub fn LLVMRustDestroyArchive(AR: &'static mut Archive); pub fn LLVMRustGetSectionName(SI: &SectionIterator, data: &mut *const c_char) -> size_t; +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString); +} +extern "C" { pub fn LLVMContextSetDiagnosticHandler(C: &Context, Handler: DiagnosticHandler, DiagnosticContext: *mut c_void); +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustUnpackOptimizationDiagnostic(DI: &'a DiagnosticInfo, pass_name_out: &RustString, function_out: &mut Option<&'a Value>, @@ -1493,20 +1510,34 @@ extern "C" { loc_column_out: &mut c_uint, loc_filename_out: &RustString, message_out: &RustString); +} + +extern "C" { pub fn LLVMRustUnpackInlineAsmDiagnostic(DI: &'a DiagnosticInfo, cookie_out: &mut c_uint, message_out: &mut Option<&'a Twine>, instruction_out: &mut Option<&'a Value>); +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustWriteDiagnosticInfoToString(DI: &DiagnosticInfo, s: &RustString); +} + +extern "C" { pub fn LLVMRustGetDiagInfoKind(DI: &DiagnosticInfo) -> DiagnosticKind; pub fn LLVMRustSetInlineAsmDiagnosticHandler(C: &Context, H: InlineAsmDiagHandler, CX: *mut c_void); +} +#[allow(improper_ctypes)] // FIXME(#52456) needed for RustString. +extern "C" { pub fn LLVMRustWriteSMDiagnosticToString(d: &SMDiagnostic, s: &RustString); +} +extern "C" { pub fn LLVMRustWriteArchive(Dst: *const c_char, NumMembers: size_t, Members: *const RustArchiveMemberRef, @@ -1515,7 +1546,7 @@ extern "C" { -> LLVMRustResult; pub fn LLVMRustArchiveMemberNew(Filename: *const c_char, Name: *const c_char, - Child: Option>) + Child: Option<&ArchiveChild>) -> RustArchiveMemberRef; pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef);