2003-07-21 Martin Baulig <martin@ximian.com>
authorMartin Baulig <martin@novell.com>
Mon, 21 Jul 2003 17:19:12 +0000 (17:19 -0000)
committerMartin Baulig <martin@novell.com>
Mon, 21 Jul 2003 17:19:12 +0000 (17:19 -0000)
* class.cs (TypeContainer.CheckPairedOperators): Added CS0660 and
CS0661 checks; fixes bug #30442.

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

mcs/mcs/ChangeLog
mcs/mcs/class.cs

index 7ba313d0651e8b038b0392381657b69514a568ff..d8ae149474749c23e7cbe20da386fada5c2b55d1 100755 (executable)
@@ -1,3 +1,8 @@
+2003-07-21  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.CheckPairedOperators): Added CS0660 and
+       CS0661 checks; fixes bug #30442.
+
 2003-07-21  Martin Baulig  <martin@ximian.com>
 
        * decl.cs (AdditionResult): Added `Error'.
index 7f5f6dc332f1011875896b14a9efd6431f18312b..5024864c14a4580158f52cfbe4d4802561336bbe 100755 (executable)
@@ -1953,6 +1953,7 @@ namespace Mono.CSharp {
                        Hashtable pairs = new Hashtable (null, null);
                        Operator true_op = null;
                        Operator false_op = null;
+                       bool has_equality_or_inequality = false;
                        
                        // Register all the operators we care about.
                        foreach (Operator op in operators){
@@ -1960,9 +1961,13 @@ namespace Mono.CSharp {
                                
                                switch (op.OperatorType){
                                case Operator.OpType.Equality:
-                                       reg = 1; break;
+                                       reg = 1;
+                                       has_equality_or_inequality = true;
+                                       break;
                                case Operator.OpType.Inequality:
-                                       reg = 2; break;
+                                       reg = 2;
+                                       has_equality_or_inequality = true;
+                                       break;
 
                                case Operator.OpType.True:
                                        true_op = op;
@@ -2034,6 +2039,34 @@ namespace Mono.CSharp {
                                Report.Error (216, oe.op.Location,
                                              "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
                        }
+
+                       if ((has_equality_or_inequality) && (RootContext.WarningLevel >= 2)) {
+                               MethodSignature equals_ms = new MethodSignature (
+                                       "Equals", TypeManager.bool_type, new Type [] { TypeManager.object_type });
+                               MethodSignature hash_ms = new MethodSignature (
+                                       "GetHashCode", TypeManager.int32_type, new Type [0]);
+
+                               MemberList equals_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
+                                                                   BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
+                                                                   equals_ms);
+                               MemberList hash_ml = FindMembers (MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance |
+                                                                 BindingFlags.DeclaredOnly, MethodSignature.method_signature_filter,
+                                                                 hash_ms);
+
+                               bool equals_ok = false;
+                               if ((equals_ml != null) && (equals_ml.Count == 1))
+                                       equals_ok = equals_ml [0].DeclaringType == TypeBuilder;
+                               bool hash_ok = false;
+                               if ((hash_ml != null) && (hash_ml.Count == 1))
+                                       hash_ok = hash_ml [0].DeclaringType == TypeBuilder;
+
+                               if (!equals_ok)
+                                       Report.Warning (660, Location, "`" + Name + "' defines operator == or operator != but does " +
+                                                       "not override Object.Equals (object o)");
+                               if (!hash_ok)
+                                       Report.Warning (661, Location, "`" + Name + "' defines operator == or operator != but does " +
+                                                       "not override Object.GetHashCode ()");
+                       }
                }