[Mono-bugs] [Bug 69082][Nor] New - Regression in compiler.

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Thu, 4 Nov 2004 00:45:54 -0500 (EST)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by miguel@ximian.com.

http://bugzilla.ximian.com/show_bug.cgi?id=69082

--- shadow/69082	2004-11-04 00:45:54.000000000 -0500
+++ shadow/69082.tmp.17368	2004-11-04 00:45:54.000000000 -0500
@@ -0,0 +1,286 @@
+Bug#: 69082
+Product: Mono: Compilers
+Version: unspecified
+OS: 
+OS Details: 
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Normal
+Component: C#
+AssignedTo: mono-bugs@ximian.com                            
+ReportedBy: miguel@ximian.com               
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Regression in compiler.
+
+The following patch regressed the compiler, the test:
+
+mono/mono/tests/iface6.cs now reports:
+
+mono$ mcs iface6.cs
+iface6.cs(53) error CS0121: Ambiguous call when selecting function due to
+implicit casts
+iface6.cs(5): 'IA.Add(int)' (name of symbol related to previous error)
+iface6.cs(10): 'IB.Add(int)' (name of symbol related to previous error)
+Compilation failed: 1 error(s), 0 warnings
+
+This was caused by this patch:
+
+Index: ChangeLog
+===================================================================
+RCS file: /cvs/public/mcs/mcs/ChangeLog,v
+retrieving revision 1.1780
+retrieving revision 1.1781
+diff -u -r1.1780 -r1.1781
+--- ChangeLog	20 Oct 2004 19:52:54 -0000	1.1780
++++ ChangeLog	23 Oct 2004 22:10:25 -0000	1.1781
+@@ -1,3 +1,16 @@
++2004-10-24  Marek Safar  <marek.safar@seznam.cz>
++
++	Fixed bugs #63705, #67130
++	* decl.cs (MemberCache.MemberCache): Add parameter to distinguish
++	imported and defined interfaces.
++	(CacheEntry, EntryType): Changed to protected internal.
++
++	* class.cs (TypeContainer.DoDefineMembers): Setup cache for
++	interfaces too.
++
++	* typemanager.cs (LookupInterfaceContainer): New method.
++	Fills member container from base interfaces.
++
+ 2004-10-20  Marek Safar  <marek.safar@seznam.cz>
+ 
+ 	* class.cs (MethodCore.CheckBase): Add errors 505, 533, 544,
+Index: class.cs
+===================================================================
+RCS file: /cvs/public/mcs/mcs/class.cs,v
+retrieving revision 1.523
+retrieving revision 1.524
+diff -u -r1.523 -r1.524
+--- class.cs	20 Oct 2004 19:52:54 -0000	1.523
++++ class.cs	23 Oct 2004 22:10:25 -0000	1.524
+@@ -1315,10 +1315,8 @@
+ 			if (TypeBuilder.BaseType != null)
+ 				parent_container = TypeManager.LookupMemberContainer
+(TypeBuilder.BaseType);
+ 
+-			// TODO:
+-			//if (TypeBuilder.IsInterface) {
+-			//	parent_container = TypeManager.LookupInterfaceContainer
+(base_inteface_types);
+-			//}
++			if (TypeBuilder.IsInterface)
++				parent_container = TypeManager.LookupInterfaceContainer
+(base_inteface_types);
+ 
+  			if (IsTopLevel) {
+  				if ((ModFlags & Modifiers.NEW) != 0)
+@@ -1399,7 +1397,7 @@
+ 
+ #if CACHE
+ 			if (!(this is ClassPart))
+-				member_cache = new MemberCache (this);
++				member_cache = new MemberCache (this, false);
+ #endif
+ 
+ 			if (parts != null) {
+@@ -2986,7 +2984,7 @@
+ 						return false;
+ 					}
+ 				} else {
+-					if (parent_method.IsAbstract) {
++					if (parent_method.IsAbstract && !IsInterface) {
+ 						Report.SymbolRelatedToPreviousError (parent_method);
+ 						Report.Error (533, Location, "'{0}' hides inherited abstract
+member", GetSignatureForError (Parent));
+ 						return false;
+Index: decl.cs
+===================================================================
+RCS file: /cvs/public/mcs/mcs/decl.cs,v
+retrieving revision 1.147
+retrieving revision 1.148
+diff -u -r1.147 -r1.148
+--- decl.cs	7 Oct 2004 07:34:27 -0000	1.147
++++ decl.cs	23 Oct 2004 22:10:25 -0000	1.148
+@@ -402,7 +402,7 @@
+ 		/// </summary>
+ 		protected bool AddToContainer (MemberCore symbol, bool is_method, string
+fullname, string basename)
+ 		{
+-			if (basename == Basename) {
++			if (basename == Basename && !(this is Interface)) {
+ 				Report.SymbolRelatedToPreviousError (this);
+ 				Report.Error (542, "'{0}': member names cannot be the same as their
+enclosing type", symbol.Location, symbol.GetSignatureForError ());
+ 				return false;
+@@ -1262,7 +1262,7 @@
+ 		/// <summary>
+ 		///   Create a new MemberCache for the given IMemberContainer `container'.
+ 		/// </summary>
+-		public MemberCache (IMemberContainer container)
++		public MemberCache (IMemberContainer container, bool
+setup_inherited_interfaces)
+ 		{
+ 			this.Container = container;
+ 
+@@ -1279,8 +1279,8 @@
+ 				if (Container.ParentContainer != null)
+ 					parent = Container.ParentContainer.MemberCache;
+ 				else
+-					parent = TypeHandle.ObjectType.MemberCache;
+-				member_hash = SetupCacheForInterface (parent);
++					parent = null;
++				member_hash = SetupCacheForInterface (parent, setup_inherited_interfaces);
+ 			} else if (Container.ParentContainer != null)
+ 				member_hash = SetupCache (Container.ParentContainer.MemberCache);
+ 			else
+@@ -1306,11 +1306,13 @@
+ 		Hashtable SetupCache (MemberCache parent)
+ 		{
+ 			Hashtable hash = new Hashtable ();
++			if (parent == null)
++				return hash;
+ 
+ 			IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
+ 			while (it.MoveNext ()) {
+ 				hash [it.Key] = ((ArrayList) it.Value).Clone ();
+-                        }
++			}
+                                 
+ 			return hash;
+ 		}
+@@ -1341,9 +1343,13 @@
+ 		///   Type.GetMembers() won't return any inherited members for interface
+types,
+ 		///   so we need to do this manually.  Interfaces also inherit from
+System.Object.
+ 		/// </summary>
+-		Hashtable SetupCacheForInterface (MemberCache parent)
++		Hashtable SetupCacheForInterface (MemberCache parent, bool deep_setup)
+ 		{
+ 			Hashtable hash = SetupCache (parent);
++
++			if (!deep_setup)
++				return hash;
++
+ 			TypeExpr [] ifaces = TypeManager.GetInterfaces (Container.Type);
+ 
+ 			foreach (TypeExpr iface in ifaces) {
+@@ -1367,8 +1373,10 @@
+ 		{
+ 			// We need to call AddMembers() with a single member type at a time
+ 			// to get the member type part of CacheEntry.EntryType right.
+-			AddMembers (MemberTypes.Constructor, container);
+-			AddMembers (MemberTypes.Field, container);
++			if (!container.IsInterface) {
++				AddMembers (MemberTypes.Constructor, container);
++				AddMembers (MemberTypes.Field, container);
++			}
+ 			AddMembers (MemberTypes.Method, container);
+ 			AddMembers (MemberTypes.Property, container);
+ 			AddMembers (MemberTypes.Event, container);
+@@ -1518,7 +1526,7 @@
+ 		///   number to speed up the searching process.
+ 		/// </summary>
+ 		[Flags]
+-		protected enum EntryType {
++		protected internal enum EntryType {
+ 			None		= 0x000,
+ 
+ 			Instance	= 0x001,
+@@ -1541,7 +1549,7 @@
+ 			MaskType	= Constructor|Event|Field|Method|Property|NestedType
+ 		}
+ 
+-		protected struct CacheEntry {
++		protected internal struct CacheEntry {
+ 			public readonly IMemberContainer Container;
+ 			public readonly EntryType EntryType;
+ 			public readonly MemberInfo Member;
+Index: typemanager.cs
+===================================================================
+RCS file: /cvs/public/mcs/mcs/typemanager.cs,v
+retrieving revision 1.319
+retrieving revision 1.320
+diff -u -r1.319 -r1.320
+--- typemanager.cs	13 Oct 2004 09:06:16 -0000	1.319
++++ typemanager.cs	23 Oct 2004 22:10:25 -0000	1.320
+@@ -490,6 +490,54 @@
+ 		return builder_to_declspace [t] as TypeContainer;
+ 	}
+ 	
++	/// <summary>
++	/// Fills member container from base interfaces
++	/// </summary>
++	public static IMemberContainer LookupInterfaceContainer (Type[] types)
++	{
++		if (types == null)
++			return null;
++
++		IMemberContainer complete = null;
++		foreach (Type t in types) {
++			IMemberContainer one_type_cont = null;
++			if (t is TypeBuilder) {
++				one_type_cont = builder_to_declspace [t] as IMemberContainer;
++			} else
++				one_type_cont = TypeHandle.GetTypeHandle (t);
++
++			if (complete == null) {
++				complete = one_type_cont;
++				continue;
++			}
++
++			// We need to avoid including same member more than once
++			foreach (DictionaryEntry de in one_type_cont.MemberCache.Members) {
++				object o = complete.MemberCache.Members [de.Key];
++				if (o == null) {
++					complete.MemberCache.Members.Add (de.Key, de.Value);
++					continue;
++				}
++
++				ArrayList al_old = (ArrayList)o;
++				ArrayList al_new = (ArrayList)de.Value;
++
++				foreach (MemberCache.CacheEntry ce in al_new) {
++					bool exist = false;
++					foreach (MemberCache.CacheEntry ce_old in al_old) {
++						if (ce.Member == ce_old.Member) {
++							exist = true;
++							break;
++						}
++					}
++					if (!exist)
++						al_old.Add (ce);
++				}
++			}
++		}
++		return complete;
++	}
++
+ 	public static IMemberContainer LookupMemberContainer (Type t)
+ 	{
+ 		if (t is TypeBuilder) {
+@@ -2640,8 +2688,10 @@
+ 				// This happens with interfaces, they have a null
+ 				// basetype.  Look members up in the Object class.
+ 				//
+-				if (current_type == null)
++				if (current_type == null) {
+ 					current_type = TypeManager.object_type;
++					searching = true;
++				}
+ 			}
+ 			
+ 			if (list.Length == 0)
+@@ -2843,7 +2893,7 @@
+ 		if (type.BaseType != null)
+ 			BaseType = GetTypeHandle (type.BaseType);
+ 		this.is_interface = type.IsInterface;
+-		this.member_cache = new MemberCache (this);
++		this.member_cache = new MemberCache (this, true);
+ 	}
+ 
+ 	// IMemberContainer methods