Ejemplo n.º 1
0
			public bool IsFieldAssigned (VariableInfo var, string name)
			{
				if (/*!var.IsParameter &&*/ IsUnreachable)
					return true;

				return var.IsStructFieldAssigned (locals, name);
			}
Ejemplo n.º 2
0
		public bool IsAssigned (VariableInfo vi)
		{
			return CurrentUsageVector.IsAssigned (vi, false);
		}
Ejemplo n.º 3
0
		protected VariableInfo (VariableInfo parent, TypeInfo type)
		{
			this.Name = parent.Name;
			this.TypeInfo = type;
			this.Offset = parent.Offset + type.Offset;
			this.Parent = parent;
			this.Length = type.TotalLength;

			this.IsParameter = parent.IsParameter;

			Initialize ();
		}
Ejemplo n.º 4
0
			public bool IsAssigned (VariableInfo var, bool ignoreReachability)
			{
				if (!ignoreReachability && !var.IsParameter && IsUnreachable)
					return true;

				return var.IsAssigned (locals);
			}
Ejemplo n.º 5
0
		public void SetStructFieldAssigned (VariableInfo variable, string name)
		{
			variable.SetStructFieldAssigned (DefiniteAssignment, name);
		}
Ejemplo n.º 6
0
		void ResolveMeta (BlockContext ec)
		{
			int orig_count = parameters.Count;

			for (int i = 0; i < orig_count; ++i) {
				Parameter.Modifier mod = parameters.FixedParameters[i].ModFlags;

				if ((mod & Parameter.Modifier.OUT) != Parameter.Modifier.OUT)
					continue;

				VariableInfo vi = new VariableInfo (parameters, i, ec.FlowOffset);
				parameter_info[i].VariableInfo = vi;
				ec.FlowOffset += vi.Length;
			}
		}
Ejemplo n.º 7
0
		// <summary>
		//   A struct's constructor must always assign all fields.
		//   This method checks whether it actually does so.
		// </summary>
		public bool IsFullyInitialized (FlowBranching branching, VariableInfo vi, Location loc)
		{
			if (struct_info == null)
				return true;

			bool ok = true;
			for (int i = 0; i < struct_info.Count; i++) {
				FieldInfo field = struct_info.Fields [i];

				if (!branching.IsFieldAssigned (vi, field.Name)) {
					FieldBase fb = TypeManager.GetField (field);
					if (fb != null && (fb.ModFlags & Modifiers.BACKING_FIELD) != 0) {
						Report.Error (843, loc,
							"An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling default contructor",
							fb.GetSignatureForError ());
					} else {
						Report.Error (171, loc,
							"Field `{0}' must be fully assigned before control leaves the constructor",
							TypeManager.GetFullNameSignature (field));
					}
					ok = false;
				}
			}

			return ok;
		}
Ejemplo n.º 8
0
		public bool IsStructFieldDefinitelyAssigned (VariableInfo variable, string name)
		{
			return variable.IsStructFieldAssigned (DefiniteAssignment, name);
		}
Ejemplo n.º 9
0
		public override Expression DoResolve (EmitContext ec)
		{
			eclass = ExprClass.Variable;
			type = ec.ContainerType;

			if (ec.IsStatic){
				Error (26, "Keyword this not valid in static code");
				return null;
			}

			if (block != null)
				vi = block.ThisVariable;

			return this;
		}
Ejemplo n.º 10
0
		public bool ResolveMeta (EmitContext ec, Parameters ip)
		{
			int errors = Report.Errors;
			int orig_count = parameters.Count;

			if (top_level_branching != null)
				return true;

			if (ip != null)
				parameters = ip;

			// Assert: orig_count != parameter.Count => orig_count == 0
			if (orig_count != 0 && orig_count != parameters.Count)
				throw new InternalErrorException ("parameter information mismatch");

			int offset = Parent == null ? 0 : Parent.AssignableSlots;

			for (int i = 0; i < orig_count; ++i) {
				Parameter.Modifier mod = parameters.FixedParameters [i].ModFlags;

				if ((mod & Parameter.Modifier.OUT) != Parameter.Modifier.OUT)
					continue;

				VariableInfo vi = new VariableInfo (ip, i, offset);
				parameter_info [i].VariableInfo = vi;
				offset += vi.Length;
			}

			ResolveMeta (ec, offset);

			top_level_branching = ec.StartFlowBranching (this);

			return Report.Errors == errors;
		}
Ejemplo n.º 11
0
		// Setting `is_readonly' to false will allow you to create a writable
		// reference to a read-only variable.  This is used by foreach and using.
		public LocalVariableReference (Block block, string name, Location l,
					       VariableInfo variable_info, bool is_readonly)
			: this (block, name, l)
		{
			this.variable_info = variable_info;
			this.is_readonly = is_readonly;
		}
Ejemplo n.º 12
0
 public void SetStructFieldAssigned(VariableInfo variable, string name)
 {
     variable.SetStructFieldAssigned(DefiniteAssignment, name);
 }
Ejemplo n.º 13
0
 public void SetVariableAssigned(VariableInfo variable, bool generatedAssignment = false)
 {
     variable.SetAssigned(DefiniteAssignment, generatedAssignment);
 }
Ejemplo n.º 14
0
		public void SetAssigned (VariableInfo vi)
		{
			CurrentUsageVector.SetAssigned (vi);
		}
Ejemplo n.º 15
0
		public bool ResolveBase (EmitContext ec)
		{
			if (eclass != ExprClass.Invalid)
				return true;

			eclass = ExprClass.Variable;

			if (ec.TypeContainer.CurrentType != null)
				type = ec.TypeContainer.CurrentType;
			else
				type = ec.ContainerType;

			if (!IsThisAvailable (ec)) {
				if (ec.IsStatic) {
					Error (26, "Keyword `this' is not valid in a static property, static method, or static field initializer");
				} else {
					Report.Error (1673, loc,
						"Anonymous methods inside structs cannot access instance members of `this'. " +
						"Consider copying `this' to a local variable outside the anonymous method and using the local instead");
				}
			}

			is_struct = ec.TypeContainer is Struct;

			if (block != null) {
				if (block.Toplevel.ThisVariable != null)
					variable_info = block.Toplevel.ThisVariable.VariableInfo;

				AnonymousExpression am = ec.CurrentAnonymousMethod;
				if (am != null) {
					//
					// this is hoisted to very top level block
					//
					if (ec.IsVariableCapturingRequired) {
						//
						// TODO: it should be optimized, see test-anon-75.cs
						//
						// `this' variable has its own scope which is mostly empty
						// and causes creation of extraneous storey references.
						// Also it's hard to remove `this' dependencies when we Undo
						// this access.
						//
						AnonymousMethodStorey scope = TopToplevelBlock.Explicit.CreateAnonymousMethodStorey (ec);
						if (HoistedVariable == null) {
							TopToplevelBlock.HoistedThisVariable = scope.CaptureThis (ec, this);
						}
					}
				}
			}
			
			return true;
		}
Ejemplo n.º 16
0
 public bool IsStructFieldDefinitelyAssigned(VariableInfo variable, string name)
 {
     return(variable.IsStructFieldAssigned(DefiniteAssignment, name));
 }
Ejemplo n.º 17
0
		public bool ResolveBase (ResolveContext ec)
		{
			if (eclass != ExprClass.Invalid)
				return true;

			eclass = ExprClass.Variable;
			type = ec.CurrentType;

			if (!IsThisAvailable (ec)) {
				if (ec.IsStatic && !ec.HasSet (ResolveContext.Options.ConstantScope)) {
					ec.Report.Error (26, loc, "Keyword `this' is not valid in a static property, static method, or static field initializer");
				} else if (ec.CurrentAnonymousMethod != null) {
					ec.Report.Error (1673, loc,
						"Anonymous methods inside structs cannot access instance members of `this'. " +
						"Consider copying `this' to a local variable outside the anonymous method and using the local instead");
				} else {
					ec.Report.Error (27, loc, "Keyword `this' is not available in the current context");
				}
			}

			is_struct = type.IsValueType;

			if (block != null) {
				if (block.Toplevel.ThisVariable != null)
					variable_info = block.Toplevel.ThisVariable.VariableInfo;

				AnonymousExpression am = ec.CurrentAnonymousMethod;
				if (am != null && ec.IsVariableCapturingRequired) {
					am.SetHasThisAccess ();
				}
			}
			
			return true;
		}
Ejemplo n.º 18
0
		public void SetVariableAssigned (VariableInfo variable, bool generatedAssignment = false)
		{
			variable.SetAssigned (DefiniteAssignment, generatedAssignment);
		}
Ejemplo n.º 19
0
		Expression DoResolve (EmitContext ec, bool lvalue_instance, bool out_access)
		{
			if (!FieldInfo.IsStatic){
				if (InstanceExpression == null){
					//
					// This can happen when referencing an instance field using
					// a fully qualified type expression: TypeName.InstanceField = xxx
					// 
					SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
					return null;
				}

				// Resolve the field's instance expression while flow analysis is turned
				// off: when accessing a field "a.b", we must check whether the field
				// "a.b" is initialized, not whether the whole struct "a" is initialized.

				if (lvalue_instance) {
					using (ec.With (EmitContext.Flags.DoFlowAnalysis, false)) {
						Expression right_side =
							out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
						InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side, loc);
					}
				} else {
					ResolveFlags rf = ResolveFlags.VariableOrValue | ResolveFlags.DisableFlowAnalysis;
					InstanceExpression = InstanceExpression.Resolve (ec, rf);
				}

				if (InstanceExpression == null)
					return null;

				using (ec.Set (EmitContext.Flags.OmitStructFlowAnalysis)) {
					InstanceExpression.CheckMarshalByRefAccess (ec);
				}
			}

			// TODO: the code above uses some non-standard multi-resolve rules
			if (eclass != ExprClass.Invalid)
				return this;

			if (!ec.IsInObsoleteScope) {
				FieldBase f = TypeManager.GetField (FieldInfo);
				if (f != null) {
					f.CheckObsoleteness (loc);
				} else {
					ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
					if (oa != null)
						AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
				}
			}

			IFixedBuffer fb = AttributeTester.GetFixedBuffer (FieldInfo);
			IVariableReference var = InstanceExpression as IVariableReference;
			
			if (fb != null) {
				IFixedExpression fe = InstanceExpression as IFixedExpression;
				if (!ec.InFixedInitializer && (fe == null || !fe.IsFixed)) {
					Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
				}

				if (InstanceExpression.eclass != ExprClass.Variable) {
					Report.SymbolRelatedToPreviousError (FieldInfo);
					Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
						TypeManager.GetFullNameSignature (FieldInfo));
				} else if (var != null && var.IsHoisted) {
					AnonymousMethodExpression.Error_AddressOfCapturedVar (var, loc);
				}
				
				return new FixedBufferPtr (this, fb.ElementType, loc).Resolve (ec);
			}

			eclass = ExprClass.Variable;

			// If the instance expression is a local variable or parameter.
			if (var == null || var.VariableInfo == null)
				return this;

			VariableInfo vi = var.VariableInfo;
			if (!vi.IsFieldAssigned (ec, FieldInfo.Name, loc))
				return null;

			variable_info = vi.GetSubStruct (FieldInfo.Name);
			eclass = ExprClass.Variable;
			return this;
		}
Ejemplo n.º 20
0
		public void PrepareForFlowAnalysis (BlockContext bc)
		{
			//
			// No need for definitely assigned check for these guys
			//
			if ((flags & (Flags.Constant | Flags.ReadonlyMask | Flags.CompilerGenerated)) != 0)
				return;

			VariableInfo = new VariableInfo (this, bc.FlowOffset);
			bc.FlowOffset += VariableInfo.Length;
		}
Ejemplo n.º 21
0
        Expression DoResolve(ResolveContext ec, bool lvalue_instance, bool out_access)
        {
            if (!IsStatic){
                if (InstanceExpression == null){
                    //
                    // This can happen when referencing an instance field using
                    // a fully qualified type expression: TypeName.InstanceField = xxx
                    //
                    SimpleName.Error_ObjectRefRequired (ec, loc, GetSignatureForError ());
                    return null;
                }

                // Resolve the field's instance expression while flow analysis is turned
                // off: when accessing a field "a.b", we must check whether the field
                // "a.b" is initialized, not whether the whole struct "a" is initialized.

                if (lvalue_instance) {
                    using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
                        Expression right_side =
                            out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;

                        if (InstanceExpression != EmptyExpression.Null)
                            InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
                    }
                } else {
                    if (InstanceExpression != EmptyExpression.Null) {
                        using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
                            InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
                        }
                    }
                }

                if (InstanceExpression == null)
                    return null;

                using (ec.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
                    InstanceExpression.CheckMarshalByRefAccess (ec);
                }
            }

            if (!ec.IsObsolete) {
                ObsoleteAttribute oa = spec.GetAttributeObsolete ();
                if (oa != null)
                    AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (spec), loc, ec.Report);
            }

            var fb = spec as FixedFieldSpec;
            IVariableReference var = InstanceExpression as IVariableReference;

            if (fb != null) {
                IFixedExpression fe = InstanceExpression as IFixedExpression;
                if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
                    ec.Report.Error (1666, loc, "You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement");
                }

                if (InstanceExpression.eclass != ExprClass.Variable) {
                    ec.Report.SymbolRelatedToPreviousError (spec);
                    ec.Report.Error (1708, loc, "`{0}': Fixed size buffers can only be accessed through locals or fields",
                        TypeManager.GetFullNameSignature (spec));
                } else if (var != null && var.IsHoisted) {
                    AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, var, loc);
                }

                return new FixedBufferPtr (this, fb.ElementType, loc).Resolve (ec);
            }

            eclass = ExprClass.Variable;

            // If the instance expression is a local variable or parameter.
            if (var == null || var.VariableInfo == null)
                return this;

            VariableInfo vi = var.VariableInfo;
            if (!vi.IsFieldAssigned (ec, Name, loc))
                return null;

            variable_info = vi.GetSubStruct (Name);
            return this;
        }
Ejemplo n.º 22
0
		// <summary>
		//   A struct's constructor must always assign all fields.
		//   This method checks whether it actually does so.
		// </summary>
		public bool IsFullyInitialized (BlockContext ec, VariableInfo vi, Location loc)
		{
			if (struct_info == null)
				return true;

			bool ok = true;
			FlowBranching branching = ec.CurrentBranching;
			for (int i = 0; i < struct_info.Count; i++) {
				var field = struct_info.Fields [i];

				if (!branching.IsStructFieldAssigned (vi, field.Name)) {
					if (field.MemberDefinition is Property.BackingField) {
						ec.Report.Error (843, loc,
							"An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling the default struct contructor from a constructor initializer",
							field.GetSignatureForError ());
					} else {
						ec.Report.Error (171, loc,
							"Field `{0}' must be fully assigned before control leaves the constructor",
							field.GetSignatureForError ());
					}
					ok = false;
				}
			}

			return ok;
		}
Ejemplo n.º 23
0
		// <summary>
		//   A struct's constructor must always assign all fields.
		//   This method checks whether it actually does so.
		// </summary>
		public bool IsFullyInitialized (FlowAnalysisContext fc, VariableInfo vi, Location loc)
		{
			if (struct_info == null)
				return true;

			bool ok = true;
			for (int i = 0; i < struct_info.Count; i++) {
				var field = struct_info.Fields[i];

				if (!fc.IsStructFieldDefinitelyAssigned (vi, field.Name)) {
					var bf = field.MemberDefinition as Property.BackingFieldDeclaration;
					if (bf != null) {
						if (bf.Initializer != null)
							continue;

						fc.Report.Error (843, loc,
							"An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling the default struct contructor from a constructor initializer",
							field.GetSignatureForError ());

						ok = false;
						continue;
					}

					fc.Report.Error (171, loc,
						"Field `{0}' must be fully assigned before control leaves the constructor",
						field.GetSignatureForError ());
					ok = false;
				}
			}

			return ok;
		}
Ejemplo n.º 24
0
		protected void Initialize ()
		{
			TypeInfo[] sub_fields = TypeInfo.SubStructInfo;
			if (sub_fields != null) {
				sub_info = new VariableInfo [sub_fields.Length];
				for (int i = 0; i < sub_fields.Length; i++) {
					if (sub_fields [i] != null)
						sub_info [i] = new VariableInfo (this, sub_fields [i]);
				}
			} else
				sub_info = new VariableInfo [0];
		}
Ejemplo n.º 25
0
		public static VariableInfo Create (BlockContext bc, LocalVariable variable)
		{
			var info = new VariableInfo (variable.Name, variable.Type, bc.AssignmentInfoOffset, bc);
			bc.AssignmentInfoOffset += info.Length;
			return info;
		}
Ejemplo n.º 26
0
			public void SetAssigned (VariableInfo var)
			{
				if (!var.IsParameter && IsUnreachable)
					return;

				var.SetAssigned (locals);
			}
Ejemplo n.º 27
0
		public static VariableInfo Create (BlockContext bc, Parameter parameter)
		{
			var info = new VariableInfo (parameter.Name, parameter.Type, bc.AssignmentInfoOffset, bc) {
				IsParameter = true
			};

			bc.AssignmentInfoOffset += info.Length;
			return info;
		}
Ejemplo n.º 28
0
			public void SetFieldAssigned (VariableInfo var, string name)
			{
				if (/*!var.IsParameter &&*/ IsUnreachable)
					return;

				var.SetStructFieldAssigned (locals, name);
			}
Ejemplo n.º 29
0
		bool ResolveMeta (BlockContext ec, ParametersCompiled ip)
		{
			int errors = ec.Report.Errors;
			int orig_count = parameters.Count;

			if (ip != null)
				parameters = ip;

			// Assert: orig_count != parameter.Count => orig_count == 0
			if (orig_count != 0 && orig_count != parameters.Count)
				throw new InternalErrorException ("parameter information mismatch");

			int offset = Parent == null ? 0 : Parent.AssignableSlots;

			for (int i = 0; i < orig_count; ++i) {
				Parameter.Modifier mod = parameters.FixedParameters [i].ModFlags;

				if ((mod & Parameter.Modifier.OUT) != Parameter.Modifier.OUT)
					continue;

				VariableInfo vi = new VariableInfo (ip, i, offset);
				parameter_info [i].VariableInfo = vi;
				offset += vi.Length;
			}

			ResolveMeta (ec, offset);

			return ec.Report.Errors == errors;
		}
Ejemplo n.º 30
0
		public bool IsStructFieldAssigned (VariableInfo vi, string field_name)
		{
			return CurrentUsageVector.IsAssigned (vi, false) || CurrentUsageVector.IsFieldAssigned (vi, field_name);
		}
Ejemplo n.º 31
0
		public bool IsDefinitelyAssigned (VariableInfo variable)
		{
			return variable.IsAssigned (DefiniteAssignment);
		}
Ejemplo n.º 32
0
		public void SetFieldAssigned (VariableInfo vi, string name)
		{
			CurrentUsageVector.SetFieldAssigned (vi, name);
		}
Ejemplo n.º 33
0
 public bool IsDefinitelyAssigned(VariableInfo variable)
 {
     return(variable.IsAssigned(DefiniteAssignment));
 }