[m-rev.] diff: fix bug #97
Peter Wang
novalazy at gmail.com
Thu Jun 4 18:03:20 AEST 2009
Branches: main
compiler/erl_call_gen.m:
Don't materialise dummy input variables before making a higher order
call. This should no longer be necessary as we replace dummy inputs in
higher order calls by `false' directly. Materialising dummy variables
can cause the Erlang compiler to warn about 'unsafe' code if the
variable is materialised multiple times (although we know it's actually
safe).
Delete materialise_dummies_before_expr, now unused.
tests/valid/Mmakefile:
tests/valid/zf_erlang_bug.m:
Add test case.
diff --git a/compiler/erl_call_gen.m b/compiler/erl_call_gen.m
index 03ff0aa..e684fcc 100644
--- a/compiler/erl_call_gen.m
+++ b/compiler/erl_call_gen.m
@@ -265,31 +265,6 @@ make_nondet_call(CallTarget, InputExprs,
OutputVars, SuccessCont0,
Statement = elds_call(CallTarget, InputExprs ++ [SuccessCont]).
%-----------------------------------------------------------------------------%
-
- % materialise_dummies_before_expr(Info, Vars, Expr0, Expr)
- %
- % Materialise any variables in Vars which are of dummy types (hence proably
- % don't exist) before evaluating Expr0. We arbitrarily assign dummy
- % variables to `false', hence variables in Vars must either not exist or
- % already be bound to `false'.
- %
-:- pred materialise_dummies_before_expr(erl_gen_info::in, prog_vars::in,
- elds_expr::in, elds_expr::out) is det.
-
-materialise_dummies_before_expr(Info, Vars, Expr0, Expr) :-
- list.filter_map(assign_false_if_dummy(Info), Vars, AssignDummyVars),
- Expr = join_exprs(elds_block(AssignDummyVars), Expr0).
-
-:- pred assign_false_if_dummy(erl_gen_info::in, prog_var::in, elds_expr::out)
- is semidet.
-
-assign_false_if_dummy(Info, Var, AssignFalse) :-
- erl_gen_info_get_module_info(Info, ModuleInfo),
- erl_variable_type(Info, Var, VarType),
- check_dummy_type(ModuleInfo, VarType) = is_dummy_type,
- AssignFalse = var_eq_false(Var).
-
-%-----------------------------------------------------------------------------%
%
% Code for generic calls
%
@@ -311,11 +286,7 @@ erl_gen_higher_order_call(GenericCall, ArgVars,
Modes, Detism,
determinism_to_code_model(Detism, CallCodeModel),
CallTarget = elds_call_ho(expr_from_var(ClosureVar)),
erl_make_call_replace_dummies(!.Info, CallCodeModel, CallTarget, InputVars,
- OutputVars, MaybeSuccessExpr, DoCall),
-
- % The callee function is responsible for materialising dummy output
- % variables.
- materialise_dummies_before_expr(!.Info, InputVars, DoCall, Statement).
+ OutputVars, MaybeSuccessExpr, Statement).
%-----------------------------------------------------------------------------%
diff --git a/tests/valid/Mmakefile b/tests/valid/Mmakefile
index 73838a3..0bff3a6 100644
--- a/tests/valid/Mmakefile
+++ b/tests/valid/Mmakefile
@@ -240,7 +240,8 @@ OTHER_PROGS= \
unused_args_test2 \
vn_float \
wrapper_arg_lvals \
- zero_arity
+ zero_arity \
+ zf_erlang_bug
C_INTERFACE_PROGS = \
intermod_pragma_import
diff --git a/tests/valid/zf_erlang_bug.m b/tests/valid/zf_erlang_bug.m
new file mode 100644
index 0000000..089e907
--- /dev/null
+++ b/tests/valid/zf_erlang_bug.m
@@ -0,0 +1,53 @@
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+
+% This module results in the following error message from the Erlang compiler
+% when compiled in the erlang grade:
+%
+% Mercury/erls/zf_erlang_bug.erl:64:
+% variable 'STATE_VARIABLE_IO_1_12' unsafe in 'case' (line 43)
+%
+% This was with Mercury rotd-2009-06-02 (+ a few of the diffs posted that day).
+% To reproduce:
+%
+% mmc --grade erlang --make zf_erlang_bug.beam
+%
+% This test case is a cut-down version of the module zinc_frontend from
+% rotd-2009-05-31 of the MiniZinc distribution.
+%
+%-----------------------------------------------------------------------------%
+
+:- module zf_erlang_bug.
+:- interface.
+
+:- import_module list.
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- type writer(T) == ( pred( T, io, io) ).
+:- inst writer == ( pred(in, di, uo) is det ).
+
+:- pred do_io_stage(list(string), writer(A), A, io, io).
+:- mode do_io_stage(in, in(writer), in, di, uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+do_io_stage(StageNames, PreDumper, Input, !IO) :-
+ ( if member("foo", StageNames) then
+ PreDumper(Input, !IO)
+ else
+ true
+ ),
+ ( if member("bar", StageNames) then
+ PreDumper(Input, !IO)
+ else
+ true
+ ).
+
+%-----------------------------------------------------------------------------%
+:- end_module zf_erlang_bug.
+%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list