@ -316,9 +316,20 @@ namespace Mono.CSharp {
@@ -316,9 +316,20 @@ namespace Mono.CSharp {
TypeManager . CSharpName ( type ) , name ) ;
}
protected stat ic void Error_ValueAssignment ( ResolveContext ec , Location loc )
publ ic void Error_ValueAssignment ( ResolveContext rc , Expression rhs )
{
ec . Report . Error ( 1 3 1 , loc , "The left-hand side of an assignment must be a variable, a property or an indexer" ) ;
if ( rhs = = EmptyExpression . LValueMemberAccess | | rhs = = EmptyExpression . LValueMemberOutAccess ) {
rc . Report . SymbolRelatedToPreviousError ( type ) ;
if ( rc . CurrentInitializerVariable ! = null ) {
rc . Report . Error ( 1 9 1 8 , loc , "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer" ,
type . GetSignatureForError ( ) , GetSignatureForError ( ) ) ;
} else {
rc . Report . Error ( 1 6 1 2 , loc , "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable" ,
GetSignatureForError ( ) ) ;
}
} else {
rc . Report . Error ( 1 3 1 , loc , "The left-hand side of an assignment must be a variable, a property or an indexer" ) ;
}
}
protected void Error_VoidPointerOperation ( ResolveContext rc )
@ -391,7 +402,7 @@ namespace Mono.CSharp {
@@ -391,7 +402,7 @@ namespace Mono.CSharp {
throw ;
ec . Report . Error ( 5 8 4 , loc , "Internal compiler error: {0}" , ex . Message ) ;
return EmptyExpression . Null ; // TODO: Add location
return ErrorExpression . Instance ; // TODO: Add location
}
}
@ -432,7 +443,7 @@ namespace Mono.CSharp {
@@ -432,7 +443,7 @@ namespace Mono.CSharp {
if ( out_access )
ec . Report . Error ( 1 5 1 0 , loc , "A ref or out argument must be an assignable variable" ) ;
else
Error_ValueAssignment ( ec , loc ) ;
Error_ValueAssignment ( ec , right_side ) ;
}
return null ;
}
@ -629,15 +640,11 @@ namespace Mono.CSharp {
@@ -629,15 +640,11 @@ namespace Mono.CSharp {
}
var r = new OverloadResolver ( ctors , OverloadResolver . Restrictions . NoBaseMembers , loc ) ;
var ctor = r . ResolveMember < MethodSpec > ( rc , ref args ) ;
if ( ctor = = null )
return null ;
if ( ( ctor . Modifiers & Modifiers . PROTECTED ) ! = 0 & & ! rc . HasSet ( ResolveContext . Options . BaseInitializer ) ) {
MemberExpr . CheckProtectedMemberAccess ( rc , ctor , ctor . DeclaringType , loc ) ;
if ( ! rc . HasSet ( ResolveContext . Options . BaseInitializer ) ) {
r . InstanceQualifier = new ConstructorInstanceQualifier ( type ) ;
}
return c tor;
return r . ResolveMember < MethodSpec > ( rc , ref args ) ;
}
[Flags]
@ -884,18 +891,6 @@ namespace Mono.CSharp {
@@ -884,18 +891,6 @@ namespace Mono.CSharp {
Report . Error ( 2 1 4 , loc , "Pointers and fixed size buffers may only be used in an unsafe context" ) ;
}
protected void Error_CannotModifyIntermediateExpressionValue ( ResolveContext ec )
{
ec . Report . SymbolRelatedToPreviousError ( type ) ;
if ( ec . CurrentInitializerVariable ! = null ) {
ec . Report . Error ( 1 9 1 8 , loc , "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer" ,
TypeManager . CSharpName ( type ) , GetSignatureForError ( ) ) ;
} else {
ec . Report . Error ( 1 6 1 2 , loc , "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable" ,
GetSignatureForError ( ) ) ;
}
}
//
// Converts `source' to an int, uint, long or ulong.
//
@ -2676,7 +2671,7 @@ namespace Mono.CSharp {
@@ -2676,7 +2671,7 @@ namespace Mono.CSharp {
/// This class denotes an expression which evaluates to a member
/// of a struct or a class.
/// </summary>
public abstract class MemberExpr : Expression
public abstract class MemberExpr : Expression , OverloadResolver . IInstanceQualifier
{
//
// An instance expression associated with this member, if it's a
@ -2716,6 +2711,12 @@ namespace Mono.CSharp {
@@ -2716,6 +2711,12 @@ namespace Mono.CSharp {
get ;
}
TypeSpec OverloadResolver . IInstanceQualifier . InstanceType {
get {
return InstanceExpression . Type ;
}
}
//
// Converts best base candidate for virtual method starting from QueriedBaseType
//
@ -2780,32 +2781,41 @@ namespace Mono.CSharp {
@@ -2780,32 +2781,41 @@ namespace Mono.CSharp {
return method ;
}
protected void CheckProtectedMemberAccess < T > ( ResolveContext rc , T member ) where T : MemberSpec
protected void CheckProtectedMemberAccess ( ResolveContext rc , MemberSpec member )
{
if ( InstanceExpression = = null )
return ;
if ( ( member . Modifiers & Modifiers . PROTECTED ) ! = 0 & & ! ( InstanceExpression is This ) ) {
CheckProtectedMemberAccess ( rc , member , InstanceExpression . Type , loc ) ;
if ( ! CheckProtectedMemberAccess ( rc , member , InstanceExpression . Type ) ) {
Error_ProtectedMemberAccess ( rc , member , InstanceExpression . Type , loc ) ;
}
}
}
public static void CheckProtectedMemberAccess < T > ( ResolveContext rc , T member , TypeSpec qualifier , Location loc ) where T : MemberSpec
bool OverloadResolver . IInstanceQualifier . CheckProtectedMemberAccess ( ResolveContext rc , MemberSpec member )
{
if ( InstanceExpression = = null )
return true ;
return InstanceExpression is This | | CheckProtectedMemberAccess ( rc , member , InstanceExpression . Type ) ;
}
public static bool CheckProtectedMemberAccess < T > ( ResolveContext rc , T member , TypeSpec qualifier ) where T : MemberSpec
{
var ct = rc . CurrentType ;
if ( ct = = qualifier )
return ;
return true ;
if ( ( member . Modifiers & Modifiers . INTERNAL ) ! = 0 & & member . DeclaringType . MemberDefinition . IsInternalAsPublic ( ct . MemberDefinition . DeclaringAssembly ) )
return ;
return true ;
qualifier = qualifier . GetDefinition ( ) ;
if ( ct ! = qualifier & & ! IsSameOrBaseQualifier ( ct , qualifier ) ) {
rc . Report . SymbolRelatedToPreviousError ( member ) ;
rc . Report . Error ( 1 5 4 0 , loc ,
"Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it" ,
member . GetSignatureForError ( ) , qualifier . GetSignatureForError ( ) , ct . GetSignatureForError ( ) ) ;
return false ;
}
return true ;
}
public override bool ContainsEmitWithAwait ( )
@ -2858,6 +2868,14 @@ namespace Mono.CSharp {
@@ -2858,6 +2868,14 @@ namespace Mono.CSharp {
rc . Report . Error ( 2 0 5 , loc , "Cannot call an abstract base member `{0}'" , name ) ;
}
public static void Error_ProtectedMemberAccess ( ResolveContext rc , MemberSpec member , TypeSpec qualifier , Location loc )
{
rc . Report . SymbolRelatedToPreviousError ( member ) ;
rc . Report . Error ( 1 5 4 0 , loc ,
"Cannot access protected member `{0}' via a qualifier of type `{1}'. The qualifier must be of type `{2}' or derived from it" ,
member . GetSignatureForError ( ) , qualifier . GetSignatureForError ( ) , rc . CurrentType . GetSignatureForError ( ) ) ;
}
//
// Implements identicial simple name and type-name
//
@ -2919,6 +2937,7 @@ namespace Mono.CSharp {
@@ -2919,6 +2937,7 @@ namespace Mono.CSharp {
"An object reference is required to access non-static member `{0}'" ,
GetSignatureForError ( ) ) ;
InstanceExpression = new CompilerGeneratedThis ( type , loc ) . Resolve ( rc ) ;
return false ;
}
@ -2968,9 +2987,6 @@ namespace Mono.CSharp {
@@ -2968,9 +2987,6 @@ namespace Mono.CSharp {
// Additional checks for l-value member access
//
if ( rhs ! = null ) {
//
// TODO: It should be recursive but that would break csc compatibility
//
if ( InstanceExpression is UnboxCast ) {
rc . Report . Error ( 4 4 5 , InstanceExpression . Location , "Cannot modify the result of an unboxing conversion" ) ;
}
@ -3378,6 +3394,7 @@ namespace Mono.CSharp {
@@ -3378,6 +3394,7 @@ namespace Mono.CSharp {
var r = new OverloadResolver ( Methods , type_arguments , restr , loc ) ;
if ( ( restr & OverloadResolver . Restrictions . NoBaseMembers ) = = 0 ) {
r . BaseMembersProvider = this ;
r . InstanceQualifier = this ;
}
if ( cerrors ! = null )
@ -3406,8 +3423,6 @@ namespace Mono.CSharp {
@@ -3406,8 +3423,6 @@ namespace Mono.CSharp {
}
ResolveInstanceExpression ( ec , null ) ;
if ( InstanceExpression ! = null )
CheckProtectedMemberAccess ( ec , best_candidate ) ;
}
var base_override = CandidateToBaseOverride ( ec , best_candidate ) ;
@ -3473,6 +3488,22 @@ namespace Mono.CSharp {
@@ -3473,6 +3488,22 @@ namespace Mono.CSharp {
#endregion
}
struct ConstructorInstanceQualifier : OverloadResolver . IInstanceQualifier
{
public ConstructorInstanceQualifier ( TypeSpec type )
: this ( )
{
InstanceType = type ;
}
public TypeSpec InstanceType { get ; private set ; }
public bool CheckProtectedMemberAccess ( ResolveContext rc , MemberSpec member )
{
return MemberExpr . CheckProtectedMemberAccess ( rc , member , InstanceType ) ;
}
}
public struct OverloadResolver
{
[Flags]
@ -3501,6 +3532,12 @@ namespace Mono.CSharp {
@@ -3501,6 +3532,12 @@ namespace Mono.CSharp {
bool TypeInferenceFailed ( ResolveContext rc , MemberSpec best ) ;
}
public interface IInstanceQualifier
{
TypeSpec InstanceType { get ; }
bool CheckProtectedMemberAccess ( ResolveContext rc , MemberSpec member ) ;
}
sealed class NoBaseMembers : IBaseMembersProvider
{
public static readonly IBaseMembersProvider Instance = new NoBaseMembers ( ) ;
@ -3540,6 +3577,7 @@ namespace Mono.CSharp {
@@ -3540,6 +3577,7 @@ namespace Mono.CSharp {
TypeArguments type_arguments ;
IBaseMembersProvider base_provider ;
IErrorHandler custom_errors ;
IInstanceQualifier instance_qualifier ;
Restrictions restrictions ;
MethodGroupExpr best_candidate_extension_group ;
TypeSpec best_candidate_return_type ;
@ -3617,6 +3655,15 @@ namespace Mono.CSharp {
@@ -3617,6 +3655,15 @@ namespace Mono.CSharp {
}
}
public IInstanceQualifier InstanceQualifier {
get {
return instance_qualifier ;
}
set {
instance_qualifier = value ;
}
}
bool IsProbingOnly {
get {
return ( restrictions & Restrictions . ProbingOnly ) ! = 0 ;
@ -4446,6 +4493,11 @@ namespace Mono.CSharp {
@@ -4446,6 +4493,11 @@ namespace Mono.CSharp {
if ( rc . IsRuntimeBinder & & ! member . DeclaringType . IsAccessible ( rc ) )
continue ;
if ( ( member . Modifiers & ( Modifiers . PROTECTED | Modifiers . STATIC ) ) = = Modifiers . PROTECTED & &
instance_qualifier ! = null & & ! instance_qualifier . CheckProtectedMemberAccess ( rc , member ) ) {
continue ;
}
}
IParametersMember pm = member as IParametersMember ;
@ -4585,6 +4637,9 @@ namespace Mono.CSharp {
@@ -4585,6 +4637,9 @@ namespace Mono.CSharp {
if ( error_mode )
break ;
if ( lambda_conv_msgs ! = null & & ! lambda_conv_msgs . IsEmpty )
break ;
lambda_conv_msgs = null ;
error_mode = true ;
}
@ -4747,6 +4802,12 @@ namespace Mono.CSharp {
@@ -4747,6 +4802,12 @@ namespace Mono.CSharp {
return ;
}
if ( ( best_candidate . Modifiers & ( Modifiers . PROTECTED | Modifiers . STATIC ) ) = = Modifiers . PROTECTED & &
InstanceQualifier ! = null & & ! InstanceQualifier . CheckProtectedMemberAccess ( rc , best_candidate ) ) {
MemberExpr . Error_ProtectedMemberAccess ( rc , best_candidate , InstanceQualifier . InstanceType , loc ) ;
}
//
// For candidates which match on parameters count report more details about incorrect arguments
//
@ -5617,8 +5678,9 @@ namespace Mono.CSharp {
@@ -5617,8 +5678,9 @@ namespace Mono.CSharp {
return CreateExpressionFactoryCall ( ec , "Property" , args ) ;
}
public Expression CreateSetterTypeOfExpression ( )
public Expression CreateSetterTypeOfExpression ( ResolveContext rc )
{
DoResolveLValue ( rc , null ) ;
return new TypeOfMethod ( Setter , loc ) ;
}
@ -5838,7 +5900,7 @@ namespace Mono.CSharp {
@@ -5838,7 +5900,7 @@ namespace Mono.CSharp {
// if the property/indexer returns a value type, and we try to set a field in it
if ( right_side = = EmptyExpression . LValueMemberAccess | | right_side = = EmptyExpression . LValueMemberOutAccess ) {
Error_CannotModifyIntermediateExpressionValue ( ec ) ;
Error_ValueAssignment ( ec , right_side ) ;
}
if ( eclass = = ExprClass . Unresolved ) {