about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBjörn Steinbrink <bsteinbr@gmail.com>2014-06-18 13:01:23 +0200
committerBjörn Steinbrink <bsteinbr@gmail.com>2014-06-21 19:59:57 +0200
commitabdbaa2e19dcf6859ae781bb9b44fed483181229 (patch)
tree876ec021b8cd312ce274e5032e8f6c1380c487f2
parentf556c8cbd8af182a9dd871a4a36692a0dba7cc2e (diff)
Correctly set return type attributes on foreign function declarations
The ArgType type gives us a generic way to specify an attribute for a
type to ensure ABI conformance for foreign functions. But the code that
actually sets the argument attributes in the function declaration
only sets the attribute for the return type when the type is indirect.

Since LLVMAddAttribute() doesn't allow to set attributes on the return
type, we have to use LLVMAddFunctionAttribute() instead.

This didn't cause problems yet, because currently only some indirect
types require attributes to be set.
-rw-r--r--src/librustc/middle/trans/foreign.rs30
1 files changed, 11 insertions, 19 deletions
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index b43b47573b9..a649ba98671 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -934,22 +934,17 @@ pub fn lltype_for_foreign_fn(ccx: &CrateContext, ty: ty::t) -> Type {
 
 fn add_argument_attributes(tys: &ForeignTypes,
                            llfn: ValueRef) {
-    let mut i = 0;
-
-    if tys.fn_ty.ret_ty.is_indirect() {
-        match tys.fn_ty.ret_ty.attr {
-            Some(attr) => {
-                let llarg = get_param(llfn, i);
-                unsafe {
-                    llvm::LLVMAddAttribute(llarg, attr as c_uint);
-                }
-            }
-            None => {}
-        }
+    let mut i = if tys.fn_ty.ret_ty.is_indirect() { 1 } else { 0 };
 
-        i += 1;
+    match tys.fn_ty.ret_ty.attr {
+        Some(attr) => unsafe {
+            llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr as u64);
+        },
+        None => {}
     }
 
+    i += 1;
+
     for &arg_ty in tys.fn_ty.arg_tys.iter() {
         if arg_ty.is_ignore() {
             continue;
@@ -958,12 +953,9 @@ fn add_argument_attributes(tys: &ForeignTypes,
         if arg_ty.pad.is_some() { i += 1; }
 
         match arg_ty.attr {
-            Some(attr) => {
-                let llarg = get_param(llfn, i);
-                unsafe {
-                    llvm::LLVMAddAttribute(llarg, attr as c_uint);
-                }
-            }
+            Some(attr) => unsafe {
+                llvm::LLVMAddFunctionAttribute(llfn, i as c_uint, attr as u64);
+            },
             None => ()
         }