about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrina Popa <irinagpopa@gmail.com>2018-07-17 15:02:11 +0300
committerIrina Popa <irinagpopa@gmail.com>2018-07-30 20:10:43 +0300
commitc7669dff2af371338004cb92cd7d757bc2961d21 (patch)
tree9e78d1a1bbd917b59a93a0dc919469c74003a799
parente551ed90331e236dc8fa6dadeeaa49dcdcb0c2ef (diff)
downloadrust-c7669dff2af371338004cb92cd7d757bc2961d21.tar.gz
rust-c7669dff2af371338004cb92cd7d757bc2961d21.zip
rustc_codegen_llvm: use safe references for ArchiveChild.
-rw-r--r--src/librustc_codegen_llvm/back/archive.rs6
-rw-r--r--src/librustc_codegen_llvm/llvm/archive_ro.rs39
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs49
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 4ea97911830..d290753a5bc 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 1d215910d95..324d52bbef4 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<Child<'a>, String>;
 
     fn next(&mut self) -> Option<Result<Child<'a>, 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 2dda2dd00d2..c139868544d 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<NonNull<ArchiveChild>>)
+                                    Child: Option<&ArchiveChild>)
                                     -> RustArchiveMemberRef;
     pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef);