[m-rev.] for review: --eliminate-local-vars bug in java grade

Peter Wang novalazy at gmail.com
Tue Jun 16 12:24:51 AEST 2009


Branches: main

Fix a bug with --eliminate-local-vars on the java grade.

The MLDS does not distinguish between integer and character constants.
Although we can assign a integer constant to a char variable in Java, if the
variable is eliminated we must explicitly cast the integer to a char wherever
the variable appeared.  Due to overloading, Java cannot implicitly cast
integers to characters in method calls.

compiler/ml_unify_gen.m:
        Add an explicit cast when generating an integer constant that is
        really a character.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/elim_local_var_char.exp:
tests/hard_coded/elim_local_var_char.m:
        Add test case.

diff --git a/compiler/ml_unify_gen.m b/compiler/ml_unify_gen.m
index f64a6ea..9c3dc18 100644
--- a/compiler/ml_unify_gen.m
+++ b/compiler/ml_unify_gen.m
@@ -106,6 +106,7 @@
 :- import_module ml_backend.ml_code_gen.
 :- import_module ml_backend.ml_type_gen.
 :- import_module ml_backend.ml_util.
+:- import_module parse_tree.builtin_lib_types.
 :- import_module parse_tree.prog_type.
 :- import_module parse_tree.prog_util.

@@ -441,7 +442,17 @@ ml_gen_static_const_arg_2(Tag, VarType, Var,
StaticCons, Context, Defns, Rval,
 ml_gen_constant(Tag, VarType, Rval, !Info) :-
     (
         Tag = int_tag(Int),
-        Rval = ml_const(mlconst_int(Int))
+        IntRval = ml_const(mlconst_int(Int)),
+        % Add an explicit cast if this is a character constant.  Although we
+        % can usually rely on implicit casts, if the char variable that the
+        % constant is assigned to is eliminated, we can end up passing an int
+        % where a char is expected.  In Java, and probably any language with
+        % overloading, the explicity cast is required.
+        ( VarType = char_type ->
+            Rval = ml_unop(cast(mlds_native_char_type), IntRval)
+        ;
+            Rval = IntRval
+        )
     ;
         Tag = float_tag(Float),
         Rval = ml_const(mlconst_float(Float))
diff --git a/tests/hard_coded/Mercury.options b/tests/hard_coded/Mercury.options
index 9b84734..a2cd8e7 100644
--- a/tests/hard_coded/Mercury.options
+++ b/tests/hard_coded/Mercury.options
@@ -17,6 +17,7 @@ MCFLAGS-delay_partial_test =    --delay-partial-instantiations
 MCFLAGS-delay_partial_test2 =   --delay-partial-instantiations
 MCFLAGS-lp		=	--intermodule-optimization -O3
 MCFLAGS-boyer		=	--infer-all
+MCFLAGS-elim_local_var_char =   --eliminate-local-vars
 MCFLAGS-float_consistency =	--optimize-constant-propagation
 MCFLAGS-foreign_enum_mod1 = 	--intermodule-optimization
 MCFLAGS-foreign_enum_mod2 = 	--intermodule-optimization
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index 7a13a4b..11ee75c 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -63,6 +63,7 @@ ORDINARY_PROGS=	\
 	dupcall_types_bug \
 	ee_dummy \
 	ee_valid_test \
+	elim_local_var_char \
 	elim_special_pred \
 	equality_pred_which_requires_boxing \
 	eqv_type_bug \
diff --git a/tests/hard_coded/elim_local_var_char.exp
b/tests/hard_coded/elim_local_var_char.exp
new file mode 100644
index 0000000..a0c2753
--- /dev/null
+++ b/tests/hard_coded/elim_local_var_char.exp
@@ -0,0 +1 @@
+a!
diff --git a/tests/hard_coded/elim_local_var_char.m
b/tests/hard_coded/elim_local_var_char.m
new file mode 100644
index 0000000..34d5412
--- /dev/null
+++ b/tests/hard_coded/elim_local_var_char.m
@@ -0,0 +1,23 @@
+% Regression test.
+% When --eliminate-local-vars was enabled, we could end up passing an int to a
+% function expecting a char.  This is a type error in Java.
+
+:- module elim_local_var_char.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+main(!IO) :-
+    io.write_char('a', !IO),
+    io.write_char('!', !IO),
+    io.write_char('\n', !IO).
+
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=8 sts=4 sw=4 et
--------------------------------------------------------------------------
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