Index: ChangeLog
===================================================================
RCS file: /mono/mcs/mcs/ChangeLog,v
retrieving revision 1.915
diff -u -r1.915 ChangeLog
--- ChangeLog	13 Dec 2002 09:46:54 -0000	1.915
+++ ChangeLog	14 Dec 2002 18:29:08 -0000
@@ -1,3 +1,8 @@
+2002-12-14  Jaroslaw Kowalski <jarek@atm.com.pl>
+
+	* decl.cs: Added special case to allow overrides on "protected
+	internal" methods
+
 2002-12-13  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
 	* namespace.cs: fixed bug #35489.
Index: decl.cs
===================================================================
RCS file: /mono/mcs/mcs/decl.cs,v
retrieving revision 1.47
diff -u -r1.47 decl.cs
--- decl.cs	27 Nov 2002 17:17:19 -0000	1.47
+++ decl.cs	14 Dec 2002 18:29:09 -0000
@@ -94,16 +94,67 @@
 						      "' because it is sealed.");
 					ok = false;
 				}
-
 				//
 				// Check that the permissions are not being changed
 				//
 				MethodAttributes thisp = my_attrs & MethodAttributes.MemberAccessMask;
 				MethodAttributes parentp = mb.Attributes & MethodAttributes.MemberAccessMask;
 
-				if (thisp != parentp){
-					Error_CannotChangeAccessModifiers (parent, mb, name);
-					ok = false;
+				//
+				// special case for "protected internal"
+				//
+
+				if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem)
+				{
+					// when overriding protected internal, the method can be declared
+					// protected internal only within the same assembly
+
+					if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem)
+					{
+						if (parent.TypeBuilder.Assembly != mb.DeclaringType.Assembly)
+						{
+							// assemblies differ - report an error
+							
+							Error_CannotChangeAccessModifiers (parent, mb, name);
+						    ok = false;
+						}
+						else if (thisp != parentp)
+						{
+							// same assembly, but other attributes differ - report an error
+
+							Error_CannotChangeAccessModifiers (parent, mb, name);
+							ok = false;
+						};
+					}
+					else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family)
+					{
+						// if it's not "protected internal", it must be "protected"
+
+						Error_CannotChangeAccessModifiers (parent, mb, name);
+					    ok = false;
+					}
+					else if (parent.TypeBuilder.Assembly == mb.DeclaringType.Assembly)
+					{
+						// protected within the same assembly - an error
+						Error_CannotChangeAccessModifiers (parent, mb, name);
+						ok = false;
+					}
+
+					else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))
+							!= (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)))
+					{
+						// protected ok, but other attributes differ - report an error
+
+						Error_CannotChangeAccessModifiers (parent, mb, name);
+						ok = false;
+					}
+				}
+				else
+				{
+					if (thisp != parentp){
+						Error_CannotChangeAccessModifiers (parent, mb, name);
+						ok = false;
+					}
 				}
 			}
 
