[m-rev.] diff: --eliminate-local-vars bug in java grade (2)

Peter Wang novalazy at gmail.com
Tue Sep 29 12:12:08 AEST 2009


Branches: main

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

Previously we had fixed a problem in which an integer constant could appear in
place of a character constant in the generated java code when
--eliminate-local-vars was used.  The same problem occurs for enumeration
constants.

compiler/ml_unify_gen.m:
        Add an explicit cast when generating an integer constant which is not
        really an integer.

        Factor out some common code.

tests/hard_coded/elim_local_var_char.exp:
tests/hard_coded/elim_local_var_char.m:
        Extend test case for enumerations.


diff --git a/compiler/ml_unify_gen.m b/compiler/ml_unify_gen.m
index 859f615..95049d6 100644
--- a/compiler/ml_unify_gen.m
+++ b/compiler/ml_unify_gen.m
@@ -370,9 +370,9 @@ ml_gen_construct_tag(Tag, Type, Var, ConsId, Args, ArgModes, TakeAddr,
         (
             Args = [],
             ml_gen_var(!.Info, Var, VarLval),
-            ml_gen_constant(Tag, Type, Rval, !Info),
             ml_gen_info_get_module_info(!.Info, ModuleInfo),
             MLDS_Type = mercury_type_to_mlds_type(ModuleInfo, Type),
+            ml_gen_constant(Tag, Type, MLDS_Type, Rval, !Info),
             GroundTerm = ml_ground_term(Rval, Type, MLDS_Type),
             ml_gen_info_set_const_var(Var, GroundTerm, !Info),
             Statement = ml_gen_assign(VarLval, Rval, Context),
@@ -392,22 +392,23 @@ ml_gen_info_lookup_const_var_rval(Info, Var, Rval) :-
 
     % Generate the rval for a given constant.
     %
-:- pred ml_gen_constant(cons_tag::in, mer_type::in, mlds_rval::out,
-    ml_gen_info::in, ml_gen_info::out) is det.
+:- pred ml_gen_constant(cons_tag::in, mer_type::in, mlds_type::in,
+    mlds_rval::out, ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_constant(Tag, VarType, Rval, !Info) :-
+ml_gen_constant(Tag, VarType, MLDS_VarType, Rval, !Info) :-
     (
         Tag = int_tag(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 explicit cast is required.
-        ( VarType = char_type ->
-            Rval = ml_unop(cast(mlds_native_char_type), IntRval)
-        ;
+        % Add an explicit cast if this is not an integer constant.  Although we
+        % can usually rely on implicit casts, if the char or enumeration
+        % variable that the constant is assigned to is eliminated, we can end
+        % up passing an int where a char or enumeration is expected.  In Java,
+        % and probably any language with overloading, the explicit cast is
+        % required.
+        ( VarType = int_type ->
             Rval = IntRval
+        ;
+            Rval = ml_unop(cast(MLDS_VarType), IntRval)
         )
     ;
         Tag = float_tag(Float),
@@ -421,12 +422,10 @@ ml_gen_constant(Tag, VarType, Rval, !Info) :-
             mlds_native_int_type))
     ;
         Tag = shared_local_tag(Bits1, Num1),
-        ml_gen_type(!.Info, VarType, MLDS_Type),
-        Rval = ml_unop(cast(MLDS_Type), ml_mkword(Bits1,
+        Rval = ml_unop(cast(MLDS_VarType), ml_mkword(Bits1,
             ml_unop(std_unop(mkbody), ml_const(mlconst_int(Num1)))))
     ;
         Tag = type_ctor_info_tag(ModuleName0, TypeName, TypeArity),
-        ml_gen_type(!.Info, VarType, MLDS_VarType),
         ModuleName = fixup_builtin_module(ModuleName0),
         MLDS_Module = mercury_module_name_to_mlds(ModuleName),
         RttiTypeCtor = rtti_type_ctor(ModuleName, TypeName, TypeArity),
@@ -436,7 +435,6 @@ ml_gen_constant(Tag, VarType, Rval, !Info) :-
             ml_const(mlconst_data_addr(DataAddr)))
     ;
         Tag = base_typeclass_info_tag(ModuleName, ClassId, Instance),
-        ml_gen_type(!.Info, VarType, MLDS_VarType),
         MLDS_Module = mercury_module_name_to_mlds(ModuleName),
         TCName = generate_class_name(ClassId),
         DataAddr = data_addr(MLDS_Module, mlds_rtti(tc_rtti_id(TCName,
@@ -445,7 +443,6 @@ ml_gen_constant(Tag, VarType, Rval, !Info) :-
             ml_const(mlconst_data_addr(DataAddr)))
     ;
         Tag = tabling_info_tag(PredId, ProcId),
-        ml_gen_type(!.Info, VarType, MLDS_VarType),
         ml_gen_info_get_module_info(!.Info, ModuleInfo),
         ml_gen_pred_label(ModuleInfo, PredId, ProcId, PredLabel, PredModule),
         DataAddr = data_addr(PredModule,
@@ -463,14 +460,13 @@ ml_gen_constant(Tag, VarType, Rval, !Info) :-
     ;
         Tag = reserved_address_tag(ReservedAddr),
         ml_gen_info_get_module_info(!.Info, ModuleInfo),
-        ml_gen_type(!.Info, VarType, MLDS_VarType),
         Rval = ml_gen_reserved_address(ModuleInfo, ReservedAddr, MLDS_VarType)
     ;
         Tag = shared_with_reserved_addresses_tag(_, ThisTag),
         % Whether or not some other constructors in the type are represented
         % by reserved addresses makes a difference only when deconstructing
         % the term, not when constructing it.
-        ml_gen_constant(ThisTag, VarType, Rval, !Info)
+        ml_gen_constant(ThisTag, VarType, MLDS_VarType, Rval, !Info)
     ;
         % These tags, which are not (necessarily) constants, are handled
         % in ml_gen_construct, so we don't need to handle them here.
@@ -2085,10 +2081,10 @@ ml_gen_ground_term_conjunct_tag(ModuleInfo, Target, HighLevelData, VarTypes,
             % knows to output an enumeration constant instead of a plain int.
             % See also the comment in ml_gen_constant.
             IntRval = ml_const(mlconst_int(Int)),
-            ( VarType \= int_type ->
-                ConstRval = ml_unop(cast(MLDS_Type), IntRval)
-            ;
+            ( VarType = int_type ->
                 ConstRval = IntRval
+            ;
+                ConstRval = ml_unop(cast(MLDS_Type), IntRval)
             )
         ;
             ConsTag = float_tag(Float),
diff --git a/tests/hard_coded/elim_local_var_char.exp b/tests/hard_coded/elim_local_var_char.exp
index a0c2753..57845de 100644
--- a/tests/hard_coded/elim_local_var_char.exp
+++ b/tests/hard_coded/elim_local_var_char.exp
@@ -1 +1,2 @@
 a!
+orange
diff --git a/tests/hard_coded/elim_local_var_char.m b/tests/hard_coded/elim_local_var_char.m
index 34d5412..3ee2256 100644
--- a/tests/hard_coded/elim_local_var_char.m
+++ b/tests/hard_coded/elim_local_var_char.m
@@ -1,6 +1,7 @@
 % 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.
+% The same problem also occurred with enumerations.
 
 :- module elim_local_var_char.
 :- interface.
@@ -14,10 +15,22 @@
 
 :- implementation.
 
+:- type rhymes
+    --->    orange
+    ;       lozenge.
+
 main(!IO) :-
     io.write_char('a', !IO),
     io.write_char('!', !IO),
+    io.write_char('\n', !IO),
+    write_enum(orange, !IO),
     io.write_char('\n', !IO).
 
+:- pred write_enum(rhymes::in, io::di, io::uo) is det.
+:- pragma no_inline(write_enum/3).
+
+write_enum(X, !IO) :-
+    io.write(X, !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