about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrina Popa <irinagpopa@gmail.com>2018-07-16 16:02:31 +0300
committerIrina Popa <irinagpopa@gmail.com>2018-07-30 20:10:37 +0300
commit0ab344454047966a8cca64d0e55c372534ed866b (patch)
tree53c05d4bbd184b317bb42d81e775ded2d3aa1de9
parent92af9694b9d70a78d0fbd0d8d7d421265a244a3c (diff)
downloadrust-0ab344454047966a8cca64d0e55c372534ed866b.tar.gz
rust-0ab344454047966a8cca64d0e55c372534ed866b.zip
rustc_codegen_llvm: use safe references for OperandBundleDef.
-rw-r--r--src/librustc_codegen_llvm/builder.rs9
-rw-r--r--src/librustc_codegen_llvm/common.rs4
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs20
-rw-r--r--src/librustc_codegen_llvm/llvm/mod.rs18
4 files changed, 26 insertions, 25 deletions
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 676523b09f7..2307ad49b5b 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -23,7 +23,6 @@ use std::borrow::Cow;
 use std::ffi::CString;
 use std::ops::Range;
 use std::ptr;
-use std::ptr::NonNull;
 
 // All Builders must have an llfn associated with them
 #[must_use]
@@ -176,7 +175,7 @@ impl Builder<'a, 'll, 'tcx> {
                   args: &[&'ll Value],
                   then: &'ll BasicBlock,
                   catch: &'ll BasicBlock,
-                  bundle: Option<&OperandBundleDef>) -> &'ll Value {
+                  bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value {
         self.count_insn("invoke");
 
         debug!("Invoke {:?} with args ({:?})",
@@ -184,7 +183,7 @@ impl Builder<'a, 'll, 'tcx> {
                args);
 
         let args = self.check_call("invoke", llfn, args);
-        let bundle = bundle.as_ref().and_then(|b| NonNull::new(b.raw()));
+        let bundle = bundle.map(|b| &*b.raw);
 
         unsafe {
             llvm::LLVMRustBuildInvoke(self.llbuilder,
@@ -724,7 +723,7 @@ impl Builder<'a, 'll, 'tcx> {
     }
 
     pub fn call(&self, llfn: &'ll Value, args: &[&'ll Value],
-                bundle: Option<&OperandBundleDef>) -> &'ll Value {
+                bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value {
         self.count_insn("call");
 
         debug!("Call {:?} with args ({:?})",
@@ -732,7 +731,7 @@ impl Builder<'a, 'll, 'tcx> {
                args);
 
         let args = self.check_call("call", llfn, args);
-        let bundle = bundle.as_ref().and_then(|b| NonNull::new(b.raw()));
+        let bundle = bundle.map(|b| &*b.raw);
 
         unsafe {
             llvm::LLVMRustBuildCall(self.llbuilder, llfn, args.as_ptr(),
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index fffb3561744..2d0ef7b3eef 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -92,7 +92,7 @@ pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bo
 /// the `OperandBundleDef` value created for MSVC landing pads.
 pub struct Funclet<'ll> {
     cleanuppad: &'ll Value,
-    operand: OperandBundleDef,
+    operand: OperandBundleDef<'ll>,
 }
 
 impl Funclet<'ll> {
@@ -107,7 +107,7 @@ impl Funclet<'ll> {
         self.cleanuppad
     }
 
-    pub fn bundle(&self) -> &OperandBundleDef {
+    pub fn bundle(&self) -> &OperandBundleDef<'ll> {
         &self.operand
     }
 }
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index d55466726c2..02a7bc045d6 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -24,6 +24,7 @@ use super::debuginfo::{
 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;
@@ -381,6 +382,12 @@ pub enum ThreadLocalMode {
   LocalExec
 }
 
+extern { type Opaque; }
+struct InvariantOpaque<'a> {
+    _marker: PhantomData<&'a mut &'a ()>,
+    _opaque: Opaque,
+}
+
 // Opaque pointer types
 extern { pub type Module; }
 extern { pub type Context; }
@@ -408,8 +415,7 @@ extern { pub type DiagnosticInfo; }
 extern { pub type SMDiagnostic; }
 extern { pub type RustArchiveMember; }
 pub type RustArchiveMemberRef = *mut RustArchiveMember;
-extern { pub type OperandBundleDef; }
-pub type OperandBundleDefRef = *mut OperandBundleDef;
+pub struct OperandBundleDef<'a>(InvariantOpaque<'a>);
 extern { pub type Linker; }
 pub type LinkerRef = *mut Linker;
 
@@ -706,7 +712,7 @@ extern "C" {
                                NumArgs: c_uint,
                                Then: &'a BasicBlock,
                                Catch: &'a BasicBlock,
-                               Bundle: Option<NonNull<OperandBundleDef>>,
+                               Bundle: Option<&OperandBundleDef<'a>>,
                                Name: *const c_char)
                                -> &'a Value;
     pub fn LLVMBuildLandingPad(B: &'a Builder,
@@ -975,7 +981,7 @@ extern "C" {
                              Fn: &'a Value,
                              Args: *const &'a Value,
                              NumArgs: c_uint,
-                             Bundle: Option<NonNull<OperandBundleDef>>,
+                             Bundle: Option<&OperandBundleDef<'a>>,
                              Name: *const c_char)
                              -> &'a Value;
     pub fn LLVMBuildSelect(B: &'a Builder,
@@ -1520,10 +1526,10 @@ extern "C" {
     pub fn LLVMRustSetDataLayoutFromTargetMachine(M: &'a Module, TM: &'a TargetMachine);
 
     pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char,
-                                         Inputs: *const &Value,
+                                         Inputs: *const &'a Value,
                                          NumInputs: c_uint)
-                                         -> OperandBundleDefRef;
-    pub fn LLVMRustFreeOperandBundleDef(Bundle: OperandBundleDefRef);
+                                         -> &'a mut OperandBundleDef<'a>;
+    pub fn LLVMRustFreeOperandBundleDef(Bundle: &'a mut OperandBundleDef<'a>);
 
     pub fn LLVMRustPositionBuilderAtStart(B: &'a Builder, BB: &'a BasicBlock);
 
diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs
index c27e0d2ae86..93dd98c62dc 100644
--- a/src/librustc_codegen_llvm/llvm/mod.rs
+++ b/src/librustc_codegen_llvm/llvm/mod.rs
@@ -258,28 +258,24 @@ pub fn last_error() -> Option<String> {
     }
 }
 
-pub struct OperandBundleDef {
-    inner: OperandBundleDefRef,
+pub struct OperandBundleDef<'a> {
+    pub raw: &'a mut ffi::OperandBundleDef<'a>,
 }
 
-impl OperandBundleDef {
-    pub fn new(name: &str, vals: &[&'a Value]) -> OperandBundleDef {
+impl OperandBundleDef<'a> {
+    pub fn new(name: &str, vals: &[&'a Value]) -> Self {
         let name = CString::new(name).unwrap();
         let def = unsafe {
             LLVMRustBuildOperandBundleDef(name.as_ptr(), vals.as_ptr(), vals.len() as c_uint)
         };
-        OperandBundleDef { inner: def }
-    }
-
-    pub fn raw(&self) -> OperandBundleDefRef {
-        self.inner
+        OperandBundleDef { raw: def }
     }
 }
 
-impl Drop for OperandBundleDef {
+impl Drop for OperandBundleDef<'a> {
     fn drop(&mut self) {
         unsafe {
-            LLVMRustFreeOperandBundleDef(self.inner);
+            LLVMRustFreeOperandBundleDef(&mut *(self.raw as *mut _));
         }
     }
 }