librustc: Don't allow return_address intrinsic in functions that don't use an out pointer.
This commit is contained in:
parent
9dac85f92d
commit
5aedcb1e91
@ -310,6 +310,13 @@ extern "rust-intrinsic" {
|
||||
/// ```
|
||||
pub fn transmute<T,U>(e: T) -> U;
|
||||
|
||||
/// Gives the address for the return value of the enclosing function.
|
||||
///
|
||||
/// Using this instrinsic in a function that does not use an out pointer
|
||||
/// will trigger a compiler error.
|
||||
#[cfg(not(stage0))]
|
||||
pub fn return_address() -> *const u8;
|
||||
|
||||
/// Returns `true` if a type requires drop glue.
|
||||
pub fn needs_drop<T>() -> bool;
|
||||
|
||||
|
@ -765,9 +765,11 @@ pub fn trans_call_inner<'a>(
|
||||
assert!(abi == synabi::RustIntrinsic);
|
||||
assert!(dest.is_some());
|
||||
|
||||
let call_info = call_info.expect("no call info for intrinsic call?");
|
||||
return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
|
||||
arg_cleanup_scope, args,
|
||||
dest.unwrap(), substs);
|
||||
dest.unwrap(), substs,
|
||||
call_info);
|
||||
}
|
||||
NamedTupleConstructor(substs, disr) => {
|
||||
assert!(dest.is_some());
|
||||
|
@ -126,7 +126,7 @@ pub fn check_intrinsics(ccx: &CrateContext) {
|
||||
pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
|
||||
callee_ty: ty::t, cleanup_scope: cleanup::CustomScopeIndex,
|
||||
args: callee::CallArgs, dest: expr::Dest,
|
||||
substs: subst::Substs) -> Result<'a> {
|
||||
substs: subst::Substs, call_info: NodeInfo) -> Result<'a> {
|
||||
|
||||
let fcx = bcx.fcx;
|
||||
let ccx = fcx.ccx;
|
||||
@ -426,9 +426,14 @@ pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
|
||||
*llargs.get(0), *llargs.get(1)),
|
||||
|
||||
(_, "return_address") => {
|
||||
PointerCast(bcx,
|
||||
bcx.fcx.llretptr.get().unwrap(),
|
||||
Type::i8p(bcx.ccx()))
|
||||
if !fcx.caller_expects_out_pointer {
|
||||
tcx.sess.span_err(call_info.span,
|
||||
"invalid use of `return_address` intrinsic: function \
|
||||
does not use out pointer");
|
||||
C_null(Type::i8p(ccx))
|
||||
} else {
|
||||
PointerCast(bcx, llvm::get_param(fcx.llfn, 0), Type::i8p(ccx))
|
||||
}
|
||||
}
|
||||
|
||||
// This requires that atomic intrinsics follow a specific naming pattern:
|
||||
|
31
src/test/compile-fail/intrinsic-return-address.rs
Normal file
31
src/test/compile-fail/intrinsic-return-address.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn return_address() -> *const u8;
|
||||
}
|
||||
|
||||
unsafe fn f() {
|
||||
let _ = return_address();
|
||||
//~^ ERROR invalid use of `return_address` intrinsic: function does not use out pointer
|
||||
}
|
||||
|
||||
unsafe fn g() -> int {
|
||||
let _ = return_address();
|
||||
//~^ ERROR invalid use of `return_address` intrinsic: function does not use out pointer
|
||||
0
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(intrinsics)];
|
||||
#![feature(intrinsics)]
|
||||
|
||||
use std::ptr;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user