Add a check for binding an alias. Good thing, as we had two instances in our library.

This commit is contained in:
Graydon Hoare 2010-11-08 15:45:30 -08:00
parent c5720b2fc4
commit 3e9be14757
4 changed files with 35 additions and 2 deletions

View File

@ -48,6 +48,29 @@ let alias_analysis_visitor
| _ -> ()
in
let check_no_alias_bindings
(fn:Ast.lval)
(args:(Ast.atom option) array)
: unit =
let fty = match lval_ty cx fn with
Ast.TY_fn tfn -> tfn
| _ -> err (Some (lval_base_id fn)) "binding non-fn"
in
let arg_slots = (fst fty).Ast.sig_input_slots in
Array.iteri
begin
fun i arg ->
match arg with
None -> ()
| Some _ ->
match arg_slots.(i).Ast.slot_mode with
Ast.MODE_local -> ()
| Ast.MODE_alias ->
err (Some (lval_base_id fn)) "binding alias slot"
end
args
in
let visit_stmt_pre s =
Stack.push s.id curr_stmt;
begin
@ -62,6 +85,9 @@ let alias_analysis_visitor
| Ast.STMT_spawn (dst, _, _, callee, args)
-> alias_call_args dst callee args
| Ast.STMT_bind (_, fn, args) ->
check_no_alias_bindings fn args
| Ast.STMT_send (_, src) -> alias src
| Ast.STMT_recv (dst, _) -> alias dst
| Ast.STMT_new_port (dst) -> alias dst

View File

@ -139,7 +139,7 @@ impure fn set(&t v, uint i, bool x) {
}
}
fn init_to_vec(&t v, uint i) -> uint {
fn init_to_vec(t v, uint i) -> uint {
if (get(v, i)) {
ret 1u;
} else {

View File

@ -35,7 +35,7 @@ fn create[T]() -> t[T] {
check (nelts == _vec.len[cell[T]](elts));
fn fill[T](uint i, uint nelts, uint lo,
&vec[cell[T]] old) -> cell[T] {
vec[cell[T]] old) -> cell[T] {
if (i < nelts) {
ret old.((lo + i) % nelts);
} else {

View File

@ -0,0 +1,7 @@
// error-pattern: binding alias slot
fn f(&int x) {}
fn main() {
bind f(10);
}