[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