--- /dev/null
+// CS1629: Unsafe code may not appear in iterators
+// Line: 17
+// Compiler options: -unsafe
+
+using System.Collections.Generic;
+
+public unsafe class TestClass
+{
+ public struct Foo {
+ public bool C;
+ }
+
+ Foo *current;
+
+ public IEnumerable<Foo> EnumeratorCurrentEvents ()
+ {
+ yield return *current;
+ }
+}
\ No newline at end of file
Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");
}
+ public static void UnsafeInsideIteratorError (ResolveContext rc, Location loc)
+ {
+ UnsafeInsideIteratorError (rc.Report, loc);
+ }
+
+ public static void UnsafeInsideIteratorError (Report report, Location loc)
+ {
+ report.Error (1629, loc, "Unsafe code may not appear in iterators");
+ }
+
//
// Converts `source' to an int, uint, long or ulong.
//
CheckProtectedMemberAccess (rc, member);
}
- if (member.MemberType.IsPointer && !rc.IsUnsafe) {
- UnsafeError (rc, loc);
+ if (member.MemberType.IsPointer) {
+ if (rc.CurrentIterator != null) {
+ UnsafeInsideIteratorError (rc, loc);
+ } else if (!rc.IsUnsafe) {
+ UnsafeError (rc, loc);
+ }
}
var dep = member.GetMissingDependencies ();
arg_count++;
}
- if (has_unsafe_arg && !ec.IsUnsafe) {
- Expression.UnsafeError (ec, loc);
+ if (has_unsafe_arg) {
+ if (ec.CurrentIterator != null) {
+ Expression.UnsafeInsideIteratorError (ec, loc);
+ } else if (!ec.IsUnsafe) {
+ Expression.UnsafeError (ec, loc);
+ }
}
//
Expression ResolveAddressOf (ResolveContext ec)
{
- if (!ec.IsUnsafe)
+ if (ec.CurrentIterator != null) {
+ UnsafeInsideIteratorError (ec, loc);
+ } else if (!ec.IsUnsafe) {
UnsafeError (ec, loc);
+ }
Expr = Expr.DoResolveLValue (ec, EmptyExpression.UnaryAddress);
if (Expr == null || Expr.eclass != ExprClass.Variable) {
is_fixed = vr.IsFixed;
vr.SetHasAddressTaken ();
- if (vr.IsHoisted) {
+ if (vr.IsHoisted && ec.CurrentIterator == null) {
AnonymousMethodExpression.Error_AddressOfCapturedVar (ec, vr, loc);
}
} else {
if (expr == null)
return null;
- if (!ec.IsUnsafe)
+ if (ec.CurrentIterator != null) {
+ UnsafeInsideIteratorError (ec, loc);
+ } else if (!ec.IsUnsafe) {
UnsafeError (ec, loc);
+ }
var pc = expr.Type as PointerContainer;
return null;
}
- if (type.IsPointer && !ec.IsUnsafe) {
- UnsafeError (ec, loc);
+ if (type.IsPointer) {
+ if (ec.CurrentIterator != null) {
+ UnsafeInsideIteratorError (ec, loc);
+ } else if (!ec.IsUnsafe) {
+ UnsafeError (ec, loc);
+ }
}
eclass = ExprClass.Value;
}
type = ac.Element;
- if (type.IsPointer && !ec.IsUnsafe) {
- UnsafeError (ec, ea.Location);
+ if (type.IsPointer) {
+ if (ec.CurrentIterator != null) {
+ UnsafeInsideIteratorError (ec, ea.Location);
+ } else if (!ec.IsUnsafe) {
+ UnsafeError (ec, ea.Location);
+ }
}
if (conditional_access_receiver)
if (!(ec.CurrentMemberDefinition is Field) && !TypeManager.VerifyUnmanaged (ec.Module, type, loc))
return null;
- if (!ec.IsUnsafe) {
+ var rc = ec as ResolveContext;
+ if (rc?.CurrentIterator != null) {
+ UnsafeInsideIteratorError (ec.Module.Compiler.Report, loc);
+ } else if (!ec.IsUnsafe) {
UnsafeError (ec.Module.Compiler.Report, loc);
}
}
if ((modifiers & Modifiers.UNSAFE) != 0) {
- parent.Compiler.Report.Error (1629, method.Location, "Unsafe code may not appear in iterators");
+ Expression.UnsafeInsideIteratorError (parent.Compiler.Report, method.Location);
}
method.Block = method.Block.ConvertToIterator (method, parent, iterator_type, is_enumerable);
public override bool Resolve (BlockContext ec)
{
if (ec.CurrentIterator != null)
- ec.Report.Error (1629, loc, "Unsafe code may not appear in iterators");
+ Expression.UnsafeInsideIteratorError (ec, loc);
using (ec.Set (ResolveContext.Options.UnsafeScope))
return Block.Resolve (ec);