Author: marek
Date: 2008-02-08 05:24:46 -0500 (Fri, 08 Feb 2008)
New Revision: 95228
Modified:
trunk/mcs/mcs/ChangeLog
trunk/mcs/mcs/class.cs
trunk/mcs/mcs/decl.cs
trunk/mcs/mcs/delegate.cs
trunk/mcs/mcs/ecore.cs
trunk/mcs/mcs/generic.cs
trunk/mcs/mcs/parameter.cs
Log:
2008-02-08 Marek Safar <[EMAIL PROTECTED]>
A fix for bugs #321394, #323028
* generic.cs, parameter.cs, ecore.cs, class.cs, decl.cs, delegate.cs:
Reworked naive IsAccessibleAs implementation to handle nested types.
Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog 2008-02-08 09:26:56 UTC (rev 95227)
+++ trunk/mcs/mcs/ChangeLog 2008-02-08 10:24:46 UTC (rev 95228)
@@ -1,3 +1,9 @@
+2008-02-08 Marek Safar <[EMAIL PROTECTED]>
+
+ A fix for bugs #321394, #323028
+ * generic.cs, parameter.cs, ecore.cs, class.cs, decl.cs, delegate.cs:
+ Reworked naive IsAccessibleAs implementation to handle nested types.
+
2008-02-05 Jb Evain <[EMAIL PROTECTED]>
* class.cs: use generic type comparison for parameters
Modified: trunk/mcs/mcs/class.cs
===================================================================
--- trunk/mcs/mcs/class.cs 2008-02-08 09:26:56 UTC (rev 95227)
+++ trunk/mcs/mcs/class.cs 2008-02-08 10:24:46 UTC (rev 95228)
@@ -1064,11 +1064,11 @@
}
if ((Kind == Kind.Interface) &&
- !iface.AsAccessible (Parent, ModFlags)) {
+ !iface.AsAccessible (this)) {
Report.Error (61, Location,
"Inconsistent
accessibility: base " +
"interface `{0}' is less
accessible " +
- "than interface `{1}'",
iface.Name,
+ "than interface `{1}'",
iface.GetSignatureForError (),
Name);
return null;
}
@@ -3128,7 +3128,7 @@
return ifaces;
}
- if (!base_class.AsAccessible (this, ModFlags)) {
+ if (!base_class.AsAccessible (this)) {
Report.SymbolRelatedToPreviousError
(base_class.Type);
Report.Error (60, Location,
"Inconsistent accessibility: base class `{0}' is less accessible than class
`{1}'",
TypeManager.CSharpName
(base_class.Type), GetSignatureForError ());
@@ -5596,7 +5596,7 @@
}
// verify accessibility
- if (!Parent.AsAccessible (MemberType, ModFlags)) {
+ if (!IsAccessibleAs (MemberType)) {
Report.SymbolRelatedToPreviousError
(MemberType);
if (this is Property)
Report.Error (53, Location,
@@ -5753,14 +5753,9 @@
if (!CheckBase ())
return false;
-
- if (!Parent.AsAccessible (MemberType, ModFlags)) {
- Report.Error (52, Location,
- "Inconsistent accessibility: field type
`" +
- TypeManager.CSharpName (MemberType) +
"' is less " +
- "accessible than field `" +
GetSignatureForError () + "'");
+
+ if (!DoDefine ())
return false;
- }
if (!IsTypePermitted ())
return false;
Modified: trunk/mcs/mcs/decl.cs
===================================================================
--- trunk/mcs/mcs/decl.cs 2008-02-08 09:26:56 UTC (rev 95227)
+++ trunk/mcs/mcs/decl.cs 2008-02-08 10:24:46 UTC (rev 95228)
@@ -353,7 +353,7 @@
member_name = new_name;
cached_name = null;
}
-
+
protected bool CheckAbstractAndExtern (bool has_block)
{
if (Parent.PartialContainer.Kind == Kind.Interface)
@@ -473,6 +473,146 @@
AttributeTester.Report_ObsoleteMessage (oa,
GetSignatureForError (), loc);
}
+ // Access level of a type.
+ const int X = 1;
+ enum AccessLevel
+ { // Each column represents `is this scope larger or equal to
Blah scope'
+ // Public Assembly Protected
+ Protected = (0 << 0) | (0 << 1) | (X << 2),
+ Public = (X << 0) | (X << 1) | (X << 2),
+ Private = (0 << 0) | (0 << 1) | (0 << 2),
+ Internal = (0 << 0) | (X << 1) | (0 << 2),
+ ProtectedOrInternal = (0 << 0) | (X << 1) | (X << 2),
+ }
+
+ static AccessLevel GetAccessLevelFromModifiers (int flags)
+ {
+ if ((flags & Modifiers.INTERNAL) != 0) {
+
+ if ((flags & Modifiers.PROTECTED) != 0)
+ return AccessLevel.ProtectedOrInternal;
+ else
+ return AccessLevel.Internal;
+
+ } else if ((flags & Modifiers.PROTECTED) != 0)
+ return AccessLevel.Protected;
+ else if ((flags & Modifiers.PRIVATE) != 0)
+ return AccessLevel.Private;
+ else
+ return AccessLevel.Public;
+ }
+
+ //
+ // Returns the access level for type `t'
+ //
+ static AccessLevel GetAccessLevelFromType (Type t)
+ {
+ if (t.IsPublic)
+ return AccessLevel.Public;
+ if (t.IsNestedPrivate)
+ return AccessLevel.Private;
+ if (t.IsNotPublic)
+ return AccessLevel.Internal;
+
+ if (t.IsNestedPublic)
+ return AccessLevel.Public;
+ if (t.IsNestedAssembly)
+ return AccessLevel.Internal;
+ if (t.IsNestedFamily)
+ return AccessLevel.Protected;
+ if (t.IsNestedFamORAssem)
+ return AccessLevel.ProtectedOrInternal;
+ if (t.IsNestedFamANDAssem)
+ throw new NotImplementedException
("NestedFamANDAssem not implemented, cant make this kind of type from c#
anyways");
+
+ // nested private is taken care of
+
+ throw new Exception ("I give up, what are you?");
+ }
+
+ //
+ // Checks whether the type P is as accessible as this member
+ //
+ public bool IsAccessibleAs (Type p)
+ {
+ //
+ // if M is private, its accessibility is the same as
this declspace.
+ // we already know that P is accessible to T before
this method, so we
+ // may return true.
+ //
+ if ((mod_flags & Modifiers.PRIVATE) != 0)
+ return true;
+
+ while (p.IsArray || p.IsPointer || p.IsByRef)
+ p = TypeManager.GetElementType (p);
+
+#if GMCS_SOURCE
+ if (p.IsGenericParameter)
+ return true;
+
+ if (TypeManager.IsGenericType (p)) {
+ foreach (Type t in p.GetGenericArguments ()) {
+ if (!IsAccessibleAs (t))
+ return false;
+ }
+ }
+#endif
+
+ for (Type p_parent = null; p != null; p = p_parent) {
+ p_parent = p.DeclaringType;
+ AccessLevel pAccess = GetAccessLevelFromType
(p);
+ if (pAccess == AccessLevel.Public)
+ continue;
+
+ bool same_access_restrictions = false;
+ for (MemberCore mc = this;
!same_access_restrictions && mc.Parent != null; mc = mc.Parent) {
+ AccessLevel al =
GetAccessLevelFromModifiers (mc.ModFlags);
+ switch (pAccess) {
+ case AccessLevel.Internal:
+ if (al ==
AccessLevel.Private || al == AccessLevel.Internal)
+
same_access_restrictions = CodeGen.Assembly.Builder == p.Assembly ||
TypeManager.IsFriendAssembly (p.Assembly);
+
+ break;
+
+ case AccessLevel.Protected:
+ if (al ==
AccessLevel.Protected)
+
same_access_restrictions = mc.Parent.IsBaseType (p_parent);
+ break;
+
+ case
AccessLevel.ProtectedOrInternal:
+ if (al ==
AccessLevel.Protected)
+
same_access_restrictions = mc.Parent.IsBaseType (p_parent);
+
+ if (al ==
AccessLevel.Internal)
+
same_access_restrictions = CodeGen.Assembly.Builder == p.Assembly ||
TypeManager.IsFriendAssembly (p.Assembly);
+
+ if (al ==
AccessLevel.ProtectedOrInternal)
+
same_access_restrictions = mc.Parent.IsBaseType (p_parent) &&
+
(CodeGen.Assembly.Builder == p.Assembly || TypeManager.IsFriendAssembly
(p.Assembly));
+
+ break;
+
+ case AccessLevel.Private:
+ //
+ // Both are private and
share same parent
+ //
+ if (al ==
AccessLevel.Private)
+
same_access_restrictions = TypeManager.IsEqual (mc.Parent.TypeBuilder,
p_parent);
+
+ break;
+
+ default:
+ throw new
InternalErrorException (al.ToString ());
+ }
+ }
+
+ if (!same_access_restrictions)
+ return false;
+ }
+
+ return true;
+ }
+
/// <summary>
/// Analyze whether CLS-Compliant verification must be execute
for this MemberCore.
/// </summary>
@@ -957,115 +1097,22 @@
return TypeManager.IsNestedFamilyAccessible
(TypeBuilder, declaring);
}
- // Access level of a type.
- const int X = 1;
- enum AccessLevel { // Each column represents `is this scope
larger or equal to Blah scope'
- // Public Assembly Protected
- Protected = (0 << 0) | (0 << 1) | (X << 2),
- Public = (X << 0) | (X << 1) | (X << 2),
- Private = (0 << 0) | (0 << 1) | (0 << 2),
- Internal = (0 << 0) | (X << 1) | (0 << 2),
- ProtectedOrInternal = (0 << 0) | (X << 1) | (X << 2),
- }
-
- static AccessLevel GetAccessLevelFromModifiers (int flags)
+ public bool IsBaseType (Type baseType)
{
- if ((flags & Modifiers.INTERNAL) != 0) {
-
- if ((flags & Modifiers.PROTECTED) != 0)
- return AccessLevel.ProtectedOrInternal;
- else
- return AccessLevel.Internal;
-
- } else if ((flags & Modifiers.PROTECTED) != 0)
- return AccessLevel.Protected;
- else if ((flags & Modifiers.PRIVATE) != 0)
- return AccessLevel.Private;
- else
- return AccessLevel.Public;
- }
+ if (TypeManager.IsInterfaceType (baseType))
+ throw new NotImplementedException ();
- // What is the effective access level of this?
- // TODO: Cache this?
- AccessLevel EffectiveAccessLevel {
- get {
- AccessLevel myAccess =
GetAccessLevelFromModifiers (ModFlags);
- if (!IsTopLevel && (Parent != null))
- return myAccess &
Parent.EffectiveAccessLevel;
- return myAccess;
+ Type type = TypeBuilder;
+ while (type != null) {
+ if (TypeManager.IsEqual (type, baseType))
+ return true;
+
+ type = type.BaseType;
}
- }
- // Return the access level for type `t'
- static AccessLevel TypeEffectiveAccessLevel (Type t)
- {
- if (t.IsPublic)
- return AccessLevel.Public;
- if (t.IsNestedPrivate)
- return AccessLevel.Private;
- if (t.IsNotPublic)
- return AccessLevel.Internal;
-
- // By now, it must be nested
- AccessLevel parent_level = TypeEffectiveAccessLevel
(t.DeclaringType);
-
- if (t.IsNestedPublic)
- return parent_level;
- if (t.IsNestedAssembly)
- return parent_level & AccessLevel.Internal;
- if (t.IsNestedFamily)
- return parent_level & AccessLevel.Protected;
- if (t.IsNestedFamORAssem)
- return parent_level &
AccessLevel.ProtectedOrInternal;
- if (t.IsNestedFamANDAssem)
- throw new NotImplementedException
("NestedFamANDAssem not implemented, cant make this kind of type from c#
anyways");
-
- // nested private is taken care of
-
- throw new Exception ("I give up, what are you?");
+ return false;
}
- //
- // This answers `is the type P, as accessible as a member M
which has the
- // accessability @flags which is declared as a nested member of
the type T, this declspace'
- //
- public bool AsAccessible (Type p, int flags)
- {
- //
- // 1) if M is private, its accessability is the same as
this declspace.
- // we already know that P is accessible to T before
this method, so we
- // may return true.
- //
-
- if ((flags & Modifiers.PRIVATE) != 0)
- return true;
-
- while (p.IsArray || p.IsPointer || p.IsByRef)
- p = TypeManager.GetElementType (p);
-
-#if GMCS_SOURCE
- if (p.IsGenericParameter)
- return true;
-
- if (TypeManager.IsGenericType (p)) {
- foreach (Type t in p.GetGenericArguments ()) {
- if (!AsAccessible (t, flags))
- return false;
- }
- }
-#endif
- AccessLevel pAccess = TypeEffectiveAccessLevel (p);
- AccessLevel mAccess = this.EffectiveAccessLevel &
- GetAccessLevelFromModifiers (flags);
-
- // for every place from which we can access M, we must
- // be able to access P as well. So, we want
- // For every bit in M and P, M_i -> P_1 == true
- // or, ~ (M -> P) == 0 <-> ~ ( ~M | P) == 0
-
- return ~ (~ mAccess | pAccess) == 0;
- }
-
private Type LookupNestedTypeInHierarchy (string name)
{
Type t = null;
Modified: trunk/mcs/mcs/delegate.cs
===================================================================
--- trunk/mcs/mcs/delegate.cs 2008-02-08 09:26:56 UTC (rev 95227)
+++ trunk/mcs/mcs/delegate.cs 2008-02-08 10:24:46 UTC (rev 95228)
@@ -211,11 +211,12 @@
// Check accessibility
foreach (Type partype in Parameters.Types){
- if (!Parent.AsAccessible (partype, ModFlags)) {
+ if (!IsAccessibleAs (partype)) {
+ Report.SymbolRelatedToPreviousError
(partype);
Report.Error (59, Location,
"Inconsistent
accessibility: parameter type `" +
TypeManager.CSharpName
(partype) + "' is less " +
- "accessible than delegate
`" + Name + "'");
+ "accessible than
delegate `" + GetSignatureForError () + "'");
return false;
}
}
@@ -226,11 +227,12 @@
ret_type = ReturnType.Type;
- if (!Parent.AsAccessible (ret_type, ModFlags)) {
+ if (!IsAccessibleAs (ret_type)) {
+ Report.SymbolRelatedToPreviousError (ret_type);
Report.Error (58, Location,
"Inconsistent accessibility:
return type `" +
TypeManager.CSharpName (ret_type)
+ "' is less " +
- "accessible than delegate `" +
Name + "'");
+ "accessible than delegate `" +
GetSignatureForError () + "'");
return false;
}
Modified: trunk/mcs/mcs/ecore.cs
===================================================================
--- trunk/mcs/mcs/ecore.cs 2008-02-08 09:26:56 UTC (rev 95227)
+++ trunk/mcs/mcs/ecore.cs 2008-02-08 10:24:46 UTC (rev 95228)
@@ -2559,9 +2559,9 @@
return ds.CheckAccessLevel (Type);
}
- public virtual bool AsAccessible (DeclSpace ds, int flags)
+ public virtual bool AsAccessible (DeclSpace ds)
{
- return ds.AsAccessible (Type, flags);
+ return ds.IsAccessibleAs (Type);
}
public virtual bool IsClass {
@@ -2905,9 +2905,9 @@
return texpr.CheckAccessLevel (ds);
}
- public override bool AsAccessible (DeclSpace ds, int flags)
+ public override bool AsAccessible (DeclSpace ds)
{
- return texpr.AsAccessible (ds, flags);
+ return texpr.AsAccessible (ds);
}
public override bool IsClass {
Modified: trunk/mcs/mcs/generic.cs
===================================================================
--- trunk/mcs/mcs/generic.cs 2008-02-08 09:26:56 UTC (rev 95227)
+++ trunk/mcs/mcs/generic.cs 2008-02-08 10:24:46 UTC (rev 95228)
@@ -243,8 +243,7 @@
if ((expr == null) || (expr.Type == null))
return false;
- // TODO: It's aleady done in
ResolveAsBaseTerminal
- if (!ec.GenericDeclContainer.AsAccessible
(fn.Type, ec.GenericDeclContainer.ModFlags)) {
+ if (!ec.GenericDeclContainer.IsAccessibleAs
(fn.Type)) {
Report.SymbolRelatedToPreviousError
(fn.Type);
Report.Error (703, loc,
"Inconsistent accessibility:
constraint type `{0}' is less accessible than `{1}'",
@@ -1504,14 +1503,14 @@
return ds.CheckAccessLevel (gt);
}
- public override bool AsAccessible (DeclSpace ds, int flags)
+ public override bool AsAccessible (DeclSpace ds)
{
foreach (Type t in atypes) {
- if (!ds.AsAccessible (t, flags))
+ if (!ds.IsAccessibleAs (t))
return false;
}
- return ds.AsAccessible (gt, flags);
+ return ds.IsAccessibleAs (gt);
}
public override bool IsClass {
Modified: trunk/mcs/mcs/parameter.cs
===================================================================
--- trunk/mcs/mcs/parameter.cs 2008-02-08 09:26:56 UTC (rev 95227)
+++ trunk/mcs/mcs/parameter.cs 2008-02-08 10:24:46 UTC (rev 95228)
@@ -337,7 +337,7 @@
if (IsTypeParameter)
return true;
- return member.ds.AsAccessible (parameter_type,
member.ModFlags);
+ return member.IsAccessibleAs (parameter_type);
}
public override IResolveContext ResolveContext {
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches