[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