Skip to content

Commit 5aedcb1

Browse files
committed
librustc: Don't allow return_address intrinsic in functions that don't use an out pointer.
1 parent 9dac85f commit 5aedcb1

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

src/libcore/intrinsics.rs

+7
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ extern "rust-intrinsic" {
310310
/// ```
311311
pub fn transmute<T,U>(e: T) -> U;
312312

313+
/// Gives the address for the return value of the enclosing function.
314+
///
315+
/// Using this instrinsic in a function that does not use an out pointer
316+
/// will trigger a compiler error.
317+
#[cfg(not(stage0))]
318+
pub fn return_address() -> *const u8;
319+
313320
/// Returns `true` if a type requires drop glue.
314321
pub fn needs_drop<T>() -> bool;
315322

src/librustc/middle/trans/callee.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -765,9 +765,11 @@ pub fn trans_call_inner<'a>(
765765
assert!(abi == synabi::RustIntrinsic);
766766
assert!(dest.is_some());
767767

768+
let call_info = call_info.expect("no call info for intrinsic call?");
768769
return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
769770
arg_cleanup_scope, args,
770-
dest.unwrap(), substs);
771+
dest.unwrap(), substs,
772+
call_info);
771773
}
772774
NamedTupleConstructor(substs, disr) => {
773775
assert!(dest.is_some());

src/librustc/middle/trans/intrinsic.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ pub fn check_intrinsics(ccx: &CrateContext) {
126126
pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
127127
callee_ty: ty::t, cleanup_scope: cleanup::CustomScopeIndex,
128128
args: callee::CallArgs, dest: expr::Dest,
129-
substs: subst::Substs) -> Result<'a> {
129+
substs: subst::Substs, call_info: NodeInfo) -> Result<'a> {
130130

131131
let fcx = bcx.fcx;
132132
let ccx = fcx.ccx;
@@ -426,9 +426,14 @@ pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
426426
*llargs.get(0), *llargs.get(1)),
427427

428428
(_, "return_address") => {
429-
PointerCast(bcx,
430-
bcx.fcx.llretptr.get().unwrap(),
431-
Type::i8p(bcx.ccx()))
429+
if !fcx.caller_expects_out_pointer {
430+
tcx.sess.span_err(call_info.span,
431+
"invalid use of `return_address` intrinsic: function \
432+
does not use out pointer");
433+
C_null(Type::i8p(ccx))
434+
} else {
435+
PointerCast(bcx, llvm::get_param(fcx.llfn, 0), Type::i8p(ccx))
436+
}
432437
}
433438

434439
// This requires that atomic intrinsics follow a specific naming pattern:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
#![allow(warnings)]
12+
#![feature(intrinsics)]
13+
14+
extern "rust-intrinsic" {
15+
fn return_address() -> *const u8;
16+
}
17+
18+
unsafe fn f() {
19+
let _ = return_address();
20+
//~^ ERROR invalid use of `return_address` intrinsic: function does not use out pointer
21+
}
22+
23+
unsafe fn g() -> int {
24+
let _ = return_address();
25+
//~^ ERROR invalid use of `return_address` intrinsic: function does not use out pointer
26+
0
27+
}
28+
29+
fn main() {}
30+
31+

src/test/run-pass/intrinsic-return-address.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(intrinsics)];
11+
#![feature(intrinsics)]
1212

1313
use std::ptr;
1414

0 commit comments

Comments
 (0)