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

Reply via email to