2002-09-12 Martin Baulig <martin@gnome.org>
authorMartin Baulig <martin@novell.com>
Thu, 12 Sep 2002 22:58:01 +0000 (22:58 -0000)
committerMartin Baulig <martin@novell.com>
Thu, 12 Sep 2002 22:58:01 +0000 (22:58 -0000)
* cfold.cs (ConstantFold.DoConstantNumericPromotions): Check whether an
implicit conversion can be done between enum types.

* enum.cs (Enum.LookupEnumValue): If the value is an EnumConstant,
check whether an implicit conversion to the current enum's UnderlyingType
exists and report an error if not.

* codegen.cs (CodeGen.Init): Delete the symbol file when compiling
without debugging support.

* delegate.cs (Delegate.CloseDelegate): Removed, use CloseType instead.
Fixes bug #30235.  Thanks to Ricardo Fern�ndez Pascual.

svn path=/trunk/mcs/; revision=7417

mcs/mcs/ChangeLog
mcs/mcs/cfold.cs
mcs/mcs/class.cs
mcs/mcs/codegen.cs
mcs/mcs/delegate.cs
mcs/mcs/ecore.cs
mcs/mcs/enum.cs
mcs/mcs/rootcontext.cs

index 0b68bacbb234101339b4ab861a2ba11afc3d0c21..3cff9e3b093d9533fa83a8c2742292fa58303a47 100755 (executable)
@@ -3,6 +3,21 @@
        * expression.cs (CheckedExpr, UnCheckedExpr): If we have a
        constant inside, return it.
 
+2002-09-12  Martin Baulig  <martin@gnome.org>
+
+       * cfold.cs (ConstantFold.DoConstantNumericPromotions): Check whether an
+       implicit conversion can be done between enum types.
+
+       * enum.cs (Enum.LookupEnumValue): If the value is an EnumConstant,
+       check whether an implicit conversion to the current enum's UnderlyingType
+       exists and report an error if not.
+
+       * codegen.cs (CodeGen.Init): Delete the symbol file when compiling
+       without debugging support.
+
+       * delegate.cs (Delegate.CloseDelegate): Removed, use CloseType instead.
+       Fixes bug #30235.  Thanks to Ricardo Fernández Pascual.
+
 2002-09-12  Martin Baulig  <martin@gnome.org>
 
        * typemanager.cs (TypeManager.IsNestedChildOf): New method.
index 9da0bc08bf8a82066c15b6b0cd47380501970008..3e8267fca4d27f73cd12978ec228ae2f8de15bb2 100755 (executable)
@@ -27,7 +27,7 @@ namespace Mono.CSharp {
                //   (uint, uint)
                //   (int, int)
                //
-               static void DoConstantNumericPromotions (Binary.Operator oper,
+               static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
                                                         ref Constant left, ref Constant right,
                                                         Location loc)
                {
@@ -116,6 +116,39 @@ namespace Mono.CSharp {
                                }
 
                                return;
+                       } else if (left is EnumConstant || right is EnumConstant){
+                               //
+                               // If either operand is an enum constant, the other one must
+                               // be implicitly convertable to that enum's underlying type.
+                               //
+                               EnumConstant match;
+                               Constant other;
+                               if (left is EnumConstant){
+                                       other = right;
+                                       match = (EnumConstant) left;
+                               } else {
+                                       other = left;
+                                       match = (EnumConstant) right;
+                               }
+
+                               bool need_check = (other is EnumConstant) ||
+                                       ((oper != Binary.Operator.Addition) &&
+                                        (oper != Binary.Operator.Subtraction));
+
+                               if (need_check &&
+                                   !Expression.ImplicitConversionExists (ec, match, other.Type)) {
+                                       Expression.Error_CannotConvertImplicit (loc, match.Type, other.Type);
+                                       left = null;
+                                       right = null;
+                                       return;
+                               }
+
+                               if (left is EnumConstant)
+                                       left = ((EnumConstant) left).Child;
+                               if (right is EnumConstant)
+                                       right = ((EnumConstant) right).Child;
+                               return;
+
                        } else {
                                //
                                // Force conversions to int32
@@ -165,7 +198,7 @@ namespace Mono.CSharp {
                        
                        switch (oper){
                        case Binary.Operator.BitwiseOr:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
                                
@@ -210,7 +243,7 @@ namespace Mono.CSharp {
                                break;
                                
                        case Binary.Operator.BitwiseAnd:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
                                
@@ -255,7 +288,7 @@ namespace Mono.CSharp {
                                break;
 
                        case Binary.Operator.ExclusiveOr:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
                                
@@ -340,7 +373,7 @@ namespace Mono.CSharp {
                                }
 
                                result = null;
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -424,7 +457,7 @@ namespace Mono.CSharp {
                                        return result;
 
                        case Binary.Operator.Subtraction:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -504,7 +537,7 @@ namespace Mono.CSharp {
                                break;
                                
                        case Binary.Operator.Multiply:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -584,7 +617,7 @@ namespace Mono.CSharp {
                                break;
 
                        case Binary.Operator.Division:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -668,7 +701,7 @@ namespace Mono.CSharp {
                                break;
                                
                        case Binary.Operator.Modulus:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -837,7 +870,7 @@ namespace Mono.CSharp {
                                        
                                }
                                
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -877,7 +910,7 @@ namespace Mono.CSharp {
                                                ((StringConstant) right).Value);
                                        
                                }
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -906,7 +939,7 @@ namespace Mono.CSharp {
                                return new BoolConstant (bool_res);
 
                        case Binary.Operator.LessThan:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -935,7 +968,7 @@ namespace Mono.CSharp {
                                return new BoolConstant (bool_res);
                                
                        case Binary.Operator.GreaterThan:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -964,7 +997,7 @@ namespace Mono.CSharp {
                                return new BoolConstant (bool_res);
 
                        case Binary.Operator.GreaterThanOrEqual:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
@@ -993,7 +1026,7 @@ namespace Mono.CSharp {
                                return new BoolConstant (bool_res);
 
                        case Binary.Operator.LessThanOrEqual:
-                               DoConstantNumericPromotions (oper, ref left, ref right, loc);
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
                                if (left == null || right == null)
                                        return null;
 
index 4559b6f8a1854e46bf43dbb183a0016ae37396f4..5c3d861765077a85c2d16bb4885bb84a73b512e5 100755 (executable)
@@ -1531,7 +1531,7 @@ namespace Mono.CSharp {
 
                        if (Delegates != null)
                                foreach (Delegate d in Delegates)
-                                       d.CloseDelegate ();
+                                       d.CloseType ();
                }
 
                public string MakeName (string n)
index bc9ca7b853445a03fc319e2ce350a67a0e8155ce..a21b8671f676454fde7bfb1d9387c531f3ff8465 100755 (executable)
@@ -8,6 +8,7 @@
 //
 
 using System;
+using System.IO;
 using System.Collections;
 using System.Reflection;
 using System.Reflection.Emit;
@@ -65,11 +66,9 @@ namespace Mono.CSharp {
                //
                // This routine initializes the Mono runtime SymbolWriter.
                //
-               static bool InitMonoSymbolWriter (string basename, string output_file,
-                                                 string[] debug_args)
+               static bool InitMonoSymbolWriter (string basename, string symbol_output,
+                                                 string exe_output_file, string[] debug_args)
                {
-                       string symbol_output = basename + ".dbg";
-
                        Type itype = SymbolWriter.GetType ();
                        if (itype == null)
                                return false;
@@ -84,7 +83,7 @@ namespace Mono.CSharp {
                                return false;
 
                        object[] args = new object [3];
-                       args [0] = output_file;
+                       args [0] = exe_output_file;
                        args [1] = symbol_output;
                        args [2] = debug_args;
 
@@ -95,8 +94,8 @@ namespace Mono.CSharp {
                //
                // Initializes the symbol writer
                //
-               static void InitializeSymbolWriter (string basename, string output_file,
-                                                   string[] args)
+               static void InitializeSymbolWriter (string basename, string symbol_output,
+                                                   string exe_output_file, string[] args)
                {
                        SymbolWriter = ModuleBuilder.GetSymWriter ();
 
@@ -123,7 +122,8 @@ namespace Mono.CSharp {
                        
                        switch (sym_type.Name){
                        case "MonoSymbolWriter":
-                               if (!InitMonoSymbolWriter (basename, output_file, args))
+                               if (!InitMonoSymbolWriter (basename, symbol_output,
+                                                          exe_output_file, args))
                                        Report.Error (
                                                -18, "Cannot initialize the symbol writer");
                                break;
@@ -161,16 +161,24 @@ namespace Mono.CSharp {
                        ModuleBuilder = AssemblyBuilder.DefineDynamicModule (
                                Basename (name), Basename (output), want_debugging_support);
 
-                       if (want_debugging_support) {
-                               int pos = output.LastIndexOf (".");
+                       int pos = output.LastIndexOf (".");
 
-                               string basename;
-                               if (pos > 0)
-                                       basename = output.Substring (0, pos);
-                               else
-                                       basename = output;
+                       string basename;
+                       if (pos > 0)
+                               basename = output.Substring (0, pos);
+                       else
+                               basename = output;
 
-                               InitializeSymbolWriter (basename, output, debug_args);
+                       string symbol_output = basename + ".dbg";
+
+                       if (want_debugging_support)
+                               InitializeSymbolWriter (basename, symbol_output, output, debug_args);
+                       else {
+                               try {
+                                       File.Delete (symbol_output);
+                               } catch {
+                                       // Ignore errors.
+                               }
                        }
                }
 
index 853d6902542ca2a2e1e0479b533f1b9227ca358a..4a58e671d5ee4680b89ed8b6fe982edbbfd80f0b 100644 (file)
@@ -489,11 +489,6 @@ namespace Mono.CSharp {
                        }\r
                }\r
 \r
-               public void CloseDelegate ()\r
-               {\r
-                       TypeBuilder.CreateType ();\r
-               }\r
-               \r
                public Expression InstanceExpression {\r
                        get {\r
                                return instance_expr;\r
index 4c468a2bd407c17ffc806931449f26296f6cce97..b6b477683254799578e3cf385dca49a9acd95ced 100755 (executable)
@@ -1043,7 +1043,7 @@ namespace Mono.CSharp {
 
                        return false;
                }
-               
+
                /// <summary>
                ///  Determines if a standard implicit conversion exists from
                ///  expr_type to target_type
@@ -3573,8 +3573,6 @@ namespace Mono.CSharp {
                                if (!me.IsStatic && (me.InstanceExpression == null))
                                        return e;
 
-                               Report.Debug (8, "RESOLVE", e, me, me.InstanceExpression, right_side);
-
                                if (!me.IsStatic &&
                                    TypeManager.IsNestedChildOf (me.InstanceExpression.Type, me.DeclaringType)) {
                                        Error (38, "Cannot access a nonstatic member of outer type `" +
index 003506f0b6e0569635986307e0ede5c9a6e3a79d..a6d9270722acb8c8a5268338eb4c450323bd73fc 100755 (executable)
@@ -257,6 +257,129 @@ namespace Mono.CSharp {
                        return;
                }
 
+               /// <summary>
+               ///  Determines if a standard implicit conversion exists from
+               ///  expr_type to target_type
+               /// </summary>
+               public static bool ImplicitConversionExists (Type expr_type, Type target_type)
+               {
+                       expr_type = TypeManager.TypeToCoreType (expr_type);
+
+                       if (expr_type == TypeManager.void_type)
+                               return false;
+                       
+                       if (expr_type == target_type)
+                               return true;
+
+                       // First numeric conversions 
+
+                       if (expr_type == TypeManager.sbyte_type){
+                               //
+                               // From sbyte to short, int, long, float, double.
+                               //
+                               if ((target_type == TypeManager.int32_type) || 
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type)  ||
+                                   (target_type == TypeManager.short_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                               
+                       } else if (expr_type == TypeManager.byte_type){
+                               //
+                               // From byte to short, ushort, int, uint, long, ulong, float, double
+                               // 
+                               if ((target_type == TypeManager.short_type) ||
+                                   (target_type == TypeManager.ushort_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+       
+                       } else if (expr_type == TypeManager.short_type){
+                               //
+                               // From short to int, long, float, double
+                               // 
+                               if ((target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if (expr_type == TypeManager.ushort_type){
+                               //
+                               // From ushort to int, uint, long, ulong, float, double
+                               //
+                               if ((target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                   
+                       } else if (expr_type == TypeManager.int32_type){
+                               //
+                               // From int to long, float, double
+                               //
+                               if ((target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if (expr_type == TypeManager.uint32_type){
+                               //
+                               // From uint to long, ulong, float, double
+                               //
+                               if ((target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if ((expr_type == TypeManager.uint64_type) ||
+                                  (expr_type == TypeManager.int64_type)) {
+                               //
+                               // From long/ulong to float, double
+                               //
+                               if ((target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                   
+                       } else if (expr_type == TypeManager.char_type){
+                               //
+                               // From char to ushort, int, uint, long, ulong, float, double
+                               // 
+                               if ((target_type == TypeManager.ushort_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+
+                       } else if (expr_type == TypeManager.float_type){
+                               //
+                               // float to double
+                               //
+                               if (target_type == TypeManager.double_type)
+                                       return true;
+                       }       
+                       
+                       return false;
+               }
+
                /// <summary>
                ///  This is used to lookup the value of an enum member. If the member is undefined,
                ///  it attempts to define it and return its value
@@ -318,26 +441,32 @@ namespace Mono.CSharp {
                                val = val.Resolve (ec);
                                in_transit.Remove (name);
                                ec.InEnumContext = old;
-                               
+
                                if (val == null)
                                        return null;
 
-                               if (IsValidEnumConstant (val)) {
-                                       c = (Constant) val;
-                                       default_value = c.GetValue ();
-                                       
-                                       if (default_value == null) {
-                                               Error_ConstantValueCannotBeConverted (c, loc);
-                                               return null;
-                                       }
-                                       
-                               } else {
+                               if (!IsValidEnumConstant (val)) {
                                        Report.Error (
                                                1008, loc,
                                                "Type byte, sbyte, short, ushort, int, uint, long, or " +
                                                "ulong expected (have: " + val + ")");
                                        return null;
                                }
+
+                               c = (Constant) val;
+                               default_value = c.GetValue ();
+
+                               if (default_value == null) {
+                                       Error_ConstantValueCannotBeConverted (c, loc);
+                                       return null;
+                               }
+
+                               if ((val is EnumConstant) &&
+                                   !ImplicitConversionExists (default_value.GetType (), UnderlyingType)) {
+                                       Expression.Error_CannotConvertImplicit (
+                                               loc, default_value.GetType (), UnderlyingType);
+                                       return null;
+                               }
                        }
 
                        FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static
index b0dd5583ad9a3967dd8de1b7d35a32c37508f3b2..22839a30dec463c60ffd2677609a47f45e03f7d2 100755 (executable)
@@ -414,7 +414,7 @@ namespace Mono.CSharp {
                        
                        if (root.Delegates != null)
                                foreach (Delegate d in root.Delegates)
-                                       d.CloseDelegate ();
+                                       d.CloseType ();
 
 
                        //