about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-05-25 21:26:08 -0500
committerAlex Crichton <alex@alexcrichton.com>2013-08-04 10:58:23 -0700
commit4ace3b74348d5bc20b22c9d94959dd828b100fc4 (patch)
treefc856b57d8ba14a2ab71ff0d8b8738bfa6755d29
parent8d2936765052f7267a16da5717d403dfe300d180 (diff)
downloadrust-4ace3b74348d5bc20b22c9d94959dd828b100fc4.tar.gz
rust-4ace3b74348d5bc20b22c9d94959dd828b100fc4.zip
Fix setting the fixed stack segment attribute on LLVM functions
At the same time create a more robust wrapper to try to prevent this type of
issue from cropping up in the future.
-rw-r--r--src/librustc/lib/llvm.rs67
-rw-r--r--src/librustc/middle/trans/base.rs41
2 files changed, 45 insertions, 63 deletions
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index 842746f8209..5ec439ce386 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -59,35 +59,35 @@ pub enum Linkage {
 
 #[deriving(Clone)]
 pub enum Attribute {
-    ZExtAttribute = 1,
-    SExtAttribute = 2,
-    NoReturnAttribute = 4,
-    InRegAttribute = 8,
-    StructRetAttribute = 16,
-    NoUnwindAttribute = 32,
-    NoAliasAttribute = 64,
-    ByValAttribute = 128,
-    NestAttribute = 256,
-    ReadNoneAttribute = 512,
-    ReadOnlyAttribute = 1024,
-    NoInlineAttribute = 2048,
-    AlwaysInlineAttribute = 4096,
-    OptimizeForSizeAttribute = 8192,
-    StackProtectAttribute = 16384,
-    StackProtectReqAttribute = 32768,
-    // 31 << 16
-    AlignmentAttribute = 2031616,
-    NoCaptureAttribute = 2097152,
-    NoRedZoneAttribute = 4194304,
-    NoImplicitFloatAttribute = 8388608,
-    NakedAttribute = 16777216,
-    InlineHintAttribute = 33554432,
-    // 7 << 26
-    StackAttribute = 469762048,
-    ReturnsTwiceAttribute = 536870912,
-    // 1 << 30
-    UWTableAttribute = 1073741824,
-    NonLazyBindAttribute = 2147483648,
+    ZExtAttribute = 1 << 0,
+    SExtAttribute = 1 << 1,
+    NoReturnAttribute = 1 << 2,
+    InRegAttribute = 1 << 3,
+    StructRetAttribute = 1 << 4,
+    NoUnwindAttribute = 1 << 5,
+    NoAliasAttribute = 1 << 6,
+    ByValAttribute = 1 << 7,
+    NestAttribute = 1 << 8,
+    ReadNoneAttribute = 1 << 9,
+    ReadOnlyAttribute = 1 << 10,
+    NoInlineAttribute = 1 << 11,
+    AlwaysInlineAttribute = 1 << 12,
+    OptimizeForSizeAttribute = 1 << 13,
+    StackProtectAttribute = 1 << 14,
+    StackProtectReqAttribute = 1 << 15,
+    AlignmentAttribute = 31 << 16,
+    NoCaptureAttribute = 1 << 21,
+    NoRedZoneAttribute = 1 << 22,
+    NoImplicitFloatAttribute = 1 << 23,
+    NakedAttribute = 1 << 24,
+    InlineHintAttribute = 1 << 25,
+    StackAttribute = 7 << 26,
+    ReturnsTwiceAttribute = 1 << 29,
+    UWTableAttribute = 1 << 30,
+    NonLazyBindAttribute = 1 << 31,
+
+    // Not added to LLVM yet, so may need to stay updated if LLVM changes.
+    FixedStackSegment = 1 << 41,
 }
 
 // enum for the LLVM IntPredicate type
@@ -2107,6 +2107,15 @@ pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef {
         llvm::LLVMConstFCmp(Pred as c_ushort, V1, V2)
     }
 }
+
+pub fn SetFunctionAttribute(Fn: ValueRef, attr: Attribute) {
+    unsafe {
+        let attr = attr as u64;
+        let lower = attr & 0xffffffff;
+        let upper = (attr >> 32) & 0xffffffff;
+        llvm::LLVMAddFunctionAttr(Fn, lower as c_uint, upper as c_uint);
+    }
+}
 /* Memory-managed object interface to type handles. */
 
 pub struct TypeNames {
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 5070d678c9f..e727907f88e 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -419,46 +419,25 @@ pub fn get_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
 }
 
 pub fn set_optimize_for_size(f: ValueRef) {
-    unsafe {
-        llvm::LLVMAddFunctionAttr(f,
-                                  lib::llvm::OptimizeForSizeAttribute
-                                    as c_uint,
-                                  0);
-    }
+    lib::llvm::SetFunctionAttribute(f, lib::llvm::OptimizeForSizeAttribute)
 }
 
 pub fn set_no_inline(f: ValueRef) {
-    unsafe {
-        llvm::LLVMAddFunctionAttr(f,
-                                  lib::llvm::NoInlineAttribute as c_uint,
-                                  0);
-    }
+    lib::llvm::SetFunctionAttribute(f, lib::llvm::NoInlineAttribute)
 }
 
 pub fn set_no_unwind(f: ValueRef) {
-    unsafe {
-        llvm::LLVMAddFunctionAttr(f,
-                                  lib::llvm::NoUnwindAttribute as c_uint,
-                                  0);
-    }
+    lib::llvm::SetFunctionAttribute(f, lib::llvm::NoUnwindAttribute)
 }
 
 // Tell LLVM to emit the information necessary to unwind the stack for the
 // function f.
 pub fn set_uwtable(f: ValueRef) {
-    unsafe {
-        llvm::LLVMAddFunctionAttr(f,
-                                  lib::llvm::UWTableAttribute as c_uint,
-                                  0);
-    }
+    lib::llvm::SetFunctionAttribute(f, lib::llvm::UWTableAttribute)
 }
 
 pub fn set_inline_hint(f: ValueRef) {
-    unsafe {
-        llvm::LLVMAddFunctionAttr(f,
-                                  lib::llvm::InlineHintAttribute as c_uint,
-                                  0);
-    }
+    lib::llvm::SetFunctionAttribute(f, lib::llvm::InlineHintAttribute)
 }
 
 pub fn set_inline_hint_if_appr(attrs: &[ast::Attribute],
@@ -473,17 +452,11 @@ pub fn set_inline_hint_if_appr(attrs: &[ast::Attribute],
 }
 
 pub fn set_always_inline(f: ValueRef) {
-    unsafe {
-        llvm::LLVMAddFunctionAttr(f,
-                                  lib::llvm::AlwaysInlineAttribute as c_uint,
-                                  0);
-    }
+    lib::llvm::SetFunctionAttribute(f, lib::llvm::AlwaysInlineAttribute)
 }
 
 pub fn set_fixed_stack_segment(f: ValueRef) {
-    unsafe {
-        llvm::LLVMAddFunctionAttr(f, 0, 1 << (39 - 32));
-    }
+    lib::llvm::SetFunctionAttribute(f, lib::llvm::FixedStackSegment)
 }
 
 pub fn set_glue_inlining(f: ValueRef, t: ty::t) {