Skip to content

Commit e94a8db

Browse files
committed
---
yaml --- r: 44954 b: refs/heads/master c: 65986ba h: refs/heads/master v: v3
1 parent d14d6af commit e94a8db

File tree

3 files changed

+61
-6
lines changed

3 files changed

+61
-6
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: eddefbc893f16ddec44dbb6b5be6adf7d84c2b53
2+
refs/heads/master: 65986ba0c0b20803dd02a5b0b71e269cbeb8336d
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d9689399d091c3265f00434a69c551a61c28dc
55
refs/heads/try: ef355f6332f83371e4acf04fc4eb940ab41d78d3

trunk/src/librustc/middle/trans/consts.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use middle::trans::expr;
2020
use middle::trans::machine;
2121
use middle::trans::type_of;
2222
use middle::ty;
23+
use util::ppaux::{expr_repr, ty_to_str};
2324

2425
use core::libc::c_uint;
2526
use syntax::{ast, ast_util, codemap, ast_map};
@@ -150,6 +151,24 @@ pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef {
150151
}
151152

152153
pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
154+
let ety = ty::expr_ty_adjusted(cx.tcx, e);
155+
let llty = type_of::sizing_type_of(cx, ety);
156+
let llconst = const_expr_unchecked(cx, e);
157+
let csize = machine::llsize_of_alloc(cx, val_ty(llconst));
158+
let tsize = machine::llsize_of_alloc(cx, llty);
159+
if csize != tsize {
160+
unsafe {
161+
llvm::LLVMDumpValue(llconst);
162+
llvm::LLVMDumpValue(C_null(llty));
163+
}
164+
cx.sess.bug(fmt!("const %s of type %s has size %u instead of %u",
165+
expr_repr(cx.tcx, e), ty_to_str(cx.tcx, ety),
166+
csize, tsize));
167+
}
168+
llconst
169+
}
170+
171+
fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
153172
unsafe {
154173
let _icx = cx.insn_ctxt("const_expr");
155174
return match /*bad*/copy e.node {
@@ -394,13 +413,22 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
394413
ast::expr_path(pth) => {
395414
assert pth.types.len() == 0;
396415
match cx.tcx.def_map.find(&e.id) {
397-
Some(ast::def_fn(def_id, purity)) => {
416+
Some(ast::def_fn(def_id, _purity)) => {
398417
assert ast_util::is_local(def_id);
399418
let f = base::get_item_val(cx, def_id.node);
400-
match purity {
401-
ast::extern_fn =>
402-
llvm::LLVMConstPointerCast(f, T_ptr(T_i8())),
403-
_ => C_struct(~[f, C_null(T_opaque_box_ptr(cx))])
419+
let ety = ty::expr_ty_adjusted(cx.tcx, e);
420+
match ty::get(ety).sty {
421+
ty::ty_bare_fn(*) | ty::ty_ptr(*) => {
422+
llvm::LLVMConstPointerCast(f, T_ptr(T_i8()))
423+
}
424+
ty::ty_closure(*) => {
425+
C_struct(~[f, C_null(T_opaque_box_ptr(cx))])
426+
}
427+
_ => {
428+
cx.sess.span_bug(e.span, fmt!(
429+
"unexpected const fn type: %s",
430+
ty_to_str(cx.tcx, ety)))
431+
}
404432
}
405433
}
406434
Some(ast::def_const(def_id)) => {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2013 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+
/*!
12+
* Try to double-check that const fns have the right size (with or
13+
* without dummy env ptr, as appropriate) by iterating a size-2 array.
14+
* If the const size differs from the runtime size, the second element
15+
* should be read as a null or otherwise wrong pointer and crash.
16+
*/
17+
18+
fn f() { }
19+
const bare_fns: &[extern fn()] = &[f, f];
20+
// NOTE Why does this not type without the struct?
21+
struct S(&fn());
22+
const closures: &[S] = &[S(f), S(f)];
23+
24+
pub fn main() {
25+
for bare_fns.each |&bare_fn| { bare_fn() }
26+
for closures.each |&closure| { (*closure)() }
27+
}

0 commit comments

Comments
 (0)