about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-04-19 10:56:25 -0700
committerbors <bors@rust-lang.org>2014-04-19 10:56:25 -0700
commit3db2b6933d33d9a27bfd82e6de083d4aebe75a3b (patch)
tree85677a3099045450ce4ff4ffe35f0ceef068813d
parentba25fecfeffdbc96d31172f483bd20cffa635b3e (diff)
parent50fb57bb107b302f7d164e22aa75c8c2a2d48756 (diff)
downloadrust-3db2b6933d33d9a27bfd82e6de083d4aebe75a3b.tar.gz
rust-3db2b6933d33d9a27bfd82e6de083d4aebe75a3b.zip
auto merge of #13628 : alexcrichton/rust/issue-13625, r=thestinger
In upgrading LLVM, only rust functions had the "split-stack" attribute added.
This commit changes the addition of LLVM's "split-stack" attribute to *always*
occur and then we remove it sometimes if the "no_split_stack" rust attribute is
present.

Closes #13625
-rw-r--r--src/librustc/lib/llvm.rs1
-rw-r--r--src/librustc/middle/trans/base.rs11
-rw-r--r--src/rustllvm/RustWrapper.cpp12
3 files changed, 22 insertions, 2 deletions
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index 10e717e550d..9e652536f6d 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -709,6 +709,7 @@ pub mod llvm {
         pub fn LLVMSetGC(Fn: ValueRef, Name: *c_char);
         pub fn LLVMAddFunctionAttr(Fn: ValueRef, PA: c_uint);
         pub fn LLVMAddFunctionAttrString(Fn: ValueRef, Name: *c_char);
+        pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, Name: *c_char);
         pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
 
         pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint);
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 95ba619e401..735b60622ed 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -199,6 +199,7 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
     lib::llvm::SetFunctionCallConv(llfn, cc);
     // Function addresses in Rust are never significant, allowing functions to be merged.
     lib::llvm::SetUnnamedAddr(llfn, true);
+    set_split_stack(llfn);
 
     llfn
 }
@@ -445,8 +446,8 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
     }
 
     // Add the no-split-stack attribute if requested
-    if !contains_name(attrs, "no_split_stack") {
-        set_split_stack(llfn);
+    if contains_name(attrs, "no_split_stack") {
+        unset_split_stack(llfn);
     }
 
     if contains_name(attrs, "cold") {
@@ -464,6 +465,12 @@ pub fn set_split_stack(f: ValueRef) {
     })
 }
 
+pub fn unset_split_stack(f: ValueRef) {
+    "split-stack".with_c_str(|buf| {
+        unsafe { llvm::LLVMRemoveFunctionAttrString(f, buf); }
+    })
+}
+
 // Double-check that we never ask LLVM to declare the same symbol twice. It
 // silently mangles such symbols, breaking our linkage model.
 pub fn note_unique_llvm_symbol(ccx: &CrateContext, sym: ~str) {
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 035a39669de..3fe1b1380da 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -77,6 +77,18 @@ extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) {
   unwrap<Function>(fn)->addFnAttr(Name);
 }
 
+extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, const char *Name) {
+  Function *f = unwrap<Function>(fn);
+  LLVMContext &C = f->getContext();
+  AttrBuilder B;
+  B.addAttribute(Name);
+  AttributeSet to_remove = AttributeSet::get(C, AttributeSet::FunctionIndex, B);
+
+  AttributeSet attrs = f->getAttributes();
+  f->setAttributes(attrs.removeAttributes(f->getContext(),
+                                          AttributeSet::FunctionIndex,
+                                          to_remove));
+}
 
 extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
   Function *A = unwrap<Function>(Fn);