Skip to content

Commit da7752b

Browse files
committed
---
yaml --- r: 152723 b: refs/heads/try2 c: 5e720aa h: refs/heads/master i: 152721: d158a60 152719: 57185bb v: v3
1 parent e51dcc3 commit da7752b

File tree

4 files changed

+83
-6
lines changed

4 files changed

+83
-6
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: abdbaa2e19dcf6859ae781bb9b44fed483181229
8+
refs/heads/try2: 5e720aac4215dcd8ba1b0fd455a737d8798baea4
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/librustc/middle/trans/foreign.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
use back::{link};
1313
use lib::llvm::llvm;
14-
use lib::llvm::{ValueRef, CallConv, StructRetAttribute, Linkage};
14+
use lib::llvm::{ValueRef, CallConv, Linkage};
1515
use lib;
1616
use middle::weak_lang_items;
1717
use middle::trans::base::push_ctxt;
@@ -373,18 +373,41 @@ pub fn trans_native_call<'a>(
373373
};
374374

375375
// A function pointer is called without the declaration available, so we have to apply
376-
// any attributes with ABI implications directly to the call instruction. Right now, the
377-
// only attribute we need to worry about is `sret`.
376+
// any attributes with ABI implications directly to the call instruction.
378377
let mut attrs = Vec::new();
379-
if fn_type.ret_ty.is_indirect() {
380-
attrs.push((1, lib::llvm::StructRetAttribute as u64));
381378

379+
// Add attributes that are always applicable, independent of the concrete foreign ABI
380+
if fn_type.ret_ty.is_indirect() {
382381
// The outptr can be noalias and nocapture because it's entirely
383382
// invisible to the program. We can also mark it as nonnull
384383
attrs.push((1, lib::llvm::NoAliasAttribute as u64));
385384
attrs.push((1, lib::llvm::NoCaptureAttribute as u64));
386385
attrs.push((1, lib::llvm::NonNullAttribute as u64));
387386
};
387+
388+
// Add attributes that depend on the concrete foreign ABI
389+
let mut arg_idx = if fn_type.ret_ty.is_indirect() { 1 } else { 0 };
390+
match fn_type.ret_ty.attr {
391+
Some(attr) => attrs.push((arg_idx, attr as u64)),
392+
_ => ()
393+
}
394+
395+
arg_idx += 1;
396+
for arg_ty in fn_type.arg_tys.iter() {
397+
if arg_ty.is_ignore() {
398+
continue;
399+
}
400+
// skip padding
401+
if arg_ty.pad.is_some() { arg_idx += 1; }
402+
403+
match arg_ty.attr {
404+
Some(attr) => attrs.push((arg_idx, attr as u64)),
405+
_ => {}
406+
}
407+
408+
arg_idx += 1;
409+
}
410+
388411
let llforeign_retval = CallWithConv(bcx,
389412
llfn,
390413
llargs_foreign.as_slice(),

branches/try2/src/rt/rust_test_helpers.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,21 @@ void
199199
rust_dbg_static_mut_check_four() {
200200
assert(rust_dbg_static_mut == 4);
201201
}
202+
203+
struct S {
204+
uint64_t x;
205+
uint64_t y;
206+
uint64_t z;
207+
};
208+
209+
uint64_t get_x(struct S s) {
210+
return s.x;
211+
}
212+
213+
uint64_t get_y(struct S s) {
214+
return s.y;
215+
}
216+
217+
uint64_t get_z(struct S s) {
218+
return s.z;
219+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub struct S {
12+
x: u64,
13+
y: u64,
14+
z: u64,
15+
}
16+
17+
#[link(name = "rust_test_helpers")]
18+
extern {
19+
pub fn get_x(x: S) -> u64;
20+
pub fn get_y(x: S) -> u64;
21+
pub fn get_z(x: S) -> u64;
22+
}
23+
24+
#[inline(never)]
25+
fn indirect_call(func: unsafe extern fn(s: S) -> u64, s: S) -> u64 {
26+
unsafe {
27+
func(s)
28+
}
29+
}
30+
31+
fn main() {
32+
let s = S { x: 1, y: 2, z: 3 };
33+
assert_eq!(s.x, indirect_call(get_x, s));
34+
assert_eq!(s.y, indirect_call(get_y, s));
35+
assert_eq!(s.z, indirect_call(get_z, s));
36+
}

0 commit comments

Comments
 (0)