diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 1999-02-19 16:28:45 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 1999-02-19 16:28:45 +0000 |
commit | 0ecbd9a5ab67f4a81314b42a91da4ebcbc50f285 (patch) | |
tree | 0d66cdbfd761c207ff4442787c4f4d53023c7144 | |
parent | f5d4b4954b59f9a5bf40e9e23fced9029e5d2dad (diff) |
Verification plus stricte des let rec (bug de Pascal Cuoq)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@2295 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r-- | bytecomp/translcore.ml | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/bytecomp/translcore.ml b/bytecomp/translcore.ml index c7eca4971..a6c7142c2 100644 --- a/bytecomp/translcore.ml +++ b/bytecomp/translcore.ml @@ -209,29 +209,52 @@ let transl_primitive p = (* To check the well-formedness of r.h.s. of "let rec" definitions *) let check_recursive_lambda idlist lam = - let rec check_top = function + let rec check_top idlist = function Lfunction(kind, params, body) as funct -> true - | Lprim(Pmakeblock(tag, mut), args) -> List.for_all check args - | Lprim(Pmakearray(Paddrarray|Pintarray), args) -> List.for_all check args - | Llet(str, id, arg, body) -> check arg & check_top body + | Lprim(Pmakeblock(tag, mut), args) -> + List.for_all (check idlist) args + | Lprim(Pmakearray(Paddrarray|Pintarray), args) -> + List.for_all (check idlist) args + | Llet(str, id, arg, body) -> + check idlist arg && check_top (add_let id arg idlist) body | Lletrec(bindings, body) -> - List.for_all (fun (id, arg) -> check arg) bindings & check_top body - | Levent (lam, _) -> check_top lam + let idlist' = add_letrec bindings idlist in + List.for_all (fun (id, arg) -> check idlist' arg) bindings && + check_top idlist' body + | Levent (lam, _) -> check_top idlist lam | _ -> false - and check = function + + and check idlist = function Lvar _ -> true | Lconst cst -> true | Lfunction(kind, params, body) -> true - | Llet(str, id, arg, body) -> check arg & check body + | Llet(str, id, arg, body) -> + check idlist arg && check (add_let id arg idlist) body | Lletrec(bindings, body) -> - List.for_all (fun (id, arg) -> check arg) bindings & check body - | Lprim(Pmakeblock(tag, mut), args) -> List.for_all check args - | Lprim(Pmakearray(Paddrarray|Pintarray), args) -> List.for_all check args - | Levent (lam, _) -> check lam + let idlist' = add_letrec bindings idlist in + List.for_all (fun (id, arg) -> check idlist' arg) bindings && + check idlist' body + | Lprim(Pmakeblock(tag, mut), args) -> + List.for_all (check idlist) args + | Lprim(Pmakearray(Paddrarray|Pintarray), args) -> + List.for_all (check idlist) args + | Levent (lam, _) -> check idlist lam | lam -> let fv = free_variables lam in List.for_all (fun id -> not(IdentSet.mem id fv)) idlist - in check_top lam + + and add_let id arg idlist = + match arg with + Lvar id' -> if List.mem id' idlist then id :: idlist else idlist + | Llet(_, _, _, body) -> add_let id body idlist + | Lletrec(_, body) -> add_let id body idlist + | _ -> idlist + + and add_letrec bindings idlist = + List.fold_right (fun (id, arg) idl -> add_let id arg idl) + bindings idlist + + in check_top idlist lam (* To propagate structured constants *) |