librustc: Don't allow return_address intrinsic in functions that don't use an out pointer.

This commit is contained in:
Luqman Aden 2014-08-05 14:38:14 -07:00
parent 9dac85f92d
commit 5aedcb1e91
5 changed files with 51 additions and 6 deletions

View File

@ -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;

View File

@ -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());

View File

@ -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:

View 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() {}

View File

@ -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;