Bug 444388 [https://bugzilla.novell.com/show_bug.cgi?id=444388] is a
pretty obscure bug that hits very few people, but I find myself among
them. Attempting to bring the latest version of C5 to Mono, I found an
issue with member resolution when interfaces hide members of parent
interfaces.

After sitting on it for a while, I was able to reach my own itch. The
full explanation is long, and if you're interested in the background of
the bug and how I came to this patch, check my *full* writeup here:
http://wiki.xpdm.us/mono/bug444388. 

The executive summary is that this patch fixes 444388, and also fixes a
bug introduced by the fix to 323096 (which caused incorrect resolution
in similar cases). As well, it adds two additional test cases to the
test suite to prevent future regressions.

If that's too succinct, let me know, and I'll respond more fully to the
list.

-- 
Marcus Griep
GPG Key ID: 0x070E3F2D
——
https://torproj.xpdm.us
Ακακια את.ψο´, 3°
Index: tests/ver-il-gmcs.xml
===================================================================
--- tests/ver-il-gmcs.xml	(revision 137658)
+++ tests/ver-il-gmcs.xml	(working copy)
@@ -42689,4 +42689,49 @@
       </method>
     </type>
   </test>
-</tests>
\ No newline at end of file
+  <test name="test-723.cs">
+    <type name="Test">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+      <method name="Int32 get_Count()">
+        <size>2</size>
+      </method>
+    </type>
+    <type name="Maine">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>21</size>
+      </method>
+    </type>
+  </test>
+  <test name="test-724.cs">
+    <type name="Concrete">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+      <method name="String A.get_Spec()">
+        <size>6</size>
+      </method>
+      <method name="String B.get_Spec()">
+        <size>6</size>
+      </method>
+      <method name="String get_Spec()">
+        <size>6</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+      <method name="Int32 DoTest(String, String, String, Int32)">
+        <size>29</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>110</size>
+      </method>
+    </type>
+  </test>
+</tests>
Index: tests/test-724.cs
===================================================================
--- tests/test-724.cs	(revision 0)
+++ tests/test-724.cs	(revision 0)
@@ -0,0 +1,46 @@
+public class Test
+{
+	private static int DoTest (string type, string expected, string actual, int failcode)
+	{
+		if (! actual.Equals (expected)) {
+			System.Console.WriteLine ("Bad {0}: Expected {1}, Was {2}",
+			                   type, expected, actual);
+			return failcode;
+		}
+		return 0;
+	}
+
+	public static int Main ()
+	{
+		int failure = 0;
+		Concrete val = new Concrete ();
+
+		failure |= DoTest("A", "A", ((A) val).Spec, 0x01);
+		failure |= DoTest("B", "B", ((B) val).Spec, 0x02);
+		failure |= DoTest("C", "B", ((C) val).Spec, 0x04);
+		failure |= DoTest("Concrete", "Concrete", val.Spec, 0x08);
+
+		return failure;
+	}
+}
+
+interface A
+{
+	string Spec { get; }
+}
+
+interface B : A
+{
+	new string Spec { get; }
+}
+
+interface C : B
+{
+}
+
+class Concrete : C
+{
+	string A.Spec { get { return "A"; } }
+	string B.Spec { get { return "B"; } }
+	public string Spec { get { return "Concrete"; } }
+}
Index: tests/test-723.cs
===================================================================
--- tests/test-723.cs	(revision 0)
+++ tests/test-723.cs	(revision 0)
@@ -0,0 +1,34 @@
+interface ICollectionValue
+{
+  int Count { get; }
+}
+
+interface ISCGCollection
+{
+  int Count { get; }
+}
+
+interface ICollection : ISCGCollection, ICollectionValue
+{
+  new int Count { get; }
+}
+
+interface ISequenced : ICollection
+{
+}
+
+class Test : ISequenced
+{
+  public int Count { get { return 0; } }
+}
+
+static class Maine
+{
+  public static int Main ()
+  {
+    ISequenced t = new Test ();
+    if (t.Count != 0)
+      return 1;
+    return 0;
+  }
+}
Index: mcs/ecore.cs
===================================================================
--- mcs/ecore.cs	(revision 137658)
+++ mcs/ecore.cs	(working copy)
@@ -715,27 +715,34 @@
 						continue;
 					}
 
-					if (non_methods == null) {
+					if (non_methods == null)
 						non_methods = new ArrayList (2);
-						non_methods.Add (m);
-						continue;
-					}
 
-					foreach (MemberInfo n_m in non_methods) {
-						if (m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (m.DeclaringType, n_m.DeclaringType))
+					foreach (MemberInfo n_m in (ArrayList)non_methods.Clone()) {
+						if (n_m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (m.DeclaringType, n_m.DeclaringType)) {
+							non_methods.Remove (n_m);
+						} else if (m.DeclaringType.IsInterface && TypeManager.ImplementsInterface (n_m.DeclaringType, m.DeclaringType)) {
 							continue;
-
-						Report.SymbolRelatedToPreviousError (m);
-						Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
-							TypeManager.GetFullNameSignature (m), TypeManager.GetFullNameSignature (n_m));
-						return null;
+						}
 					}
+					
+					non_methods.Add (m);
 				}
+				
+				if (methods.Count == 0 && non_methods != null && non_methods.Count > 1)
+				{
+					Report.SymbolRelatedToPreviousError ((MemberInfo)non_methods[1]);
+					Report.SymbolRelatedToPreviousError ((MemberInfo)non_methods[0]);
+					Report.Error (229, loc, "Ambiguity between `{0}' and `{1}'",
+						TypeManager.GetFullNameSignature ((MemberInfo)non_methods[1]),
+						TypeManager.GetFullNameSignature ((MemberInfo)non_methods[0]));
+					return null;
+				}
 
 				if (methods.Count == 0)
 					return ExprClassFromMemberInfo (container_type, (MemberInfo)non_methods [0], loc);
 
-				if (non_methods != null) {
+				if (non_methods != null && non_methods.Count > 0) {
 					MethodBase method = (MethodBase) methods [0];
 					MemberInfo non_method = (MemberInfo) non_methods [0];
 					if (method.DeclaringType == non_method.DeclaringType) {

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to