Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove or document Unsafe.AsPointer uses in tests and miscellaneous code #99272

Merged
merged 2 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class UnsafeTests
public static unsafe void ReadInt32()
{
int expected = 10;
void* address = Unsafe.AsPointer(ref expected);
void* address = Unsafe.AsPointer(ref expected); // Unsafe.AsPointer is safe since expected is on stack
hamarb123 marked this conversation as resolved.
Show resolved Hide resolved
int ret = Unsafe.Read<int>(address);
Assert.Equal(expected, ret);
}
Expand All @@ -23,7 +23,7 @@ public static unsafe void ReadInt32()
public static unsafe void WriteInt32()
{
int value = 10;
int* address = (int*)Unsafe.AsPointer(ref value);
int* address = (int*)Unsafe.AsPointer(ref value); // Unsafe.AsPointer is safe since value is on stack
int expected = 20;
Unsafe.Write(address, expected);

Expand All @@ -36,7 +36,7 @@ public static unsafe void WriteInt32()
public static unsafe void WriteBytesIntoInt32()
{
int value = 20;
int* intAddress = (int*)Unsafe.AsPointer(ref value);
int* intAddress = (int*)Unsafe.AsPointer(ref value); // Unsafe.AsPointer is safe since value is on stack
byte* byteAddress = (byte*)intAddress;
for (int i = 0; i < 4; i++)
{
Expand Down Expand Up @@ -70,7 +70,7 @@ public static unsafe void WriteBytesIntoInt32()
public static unsafe void LongIntoCompoundStruct()
{
long value = 1234567891011121314L;
long* longAddress = (long*)Unsafe.AsPointer(ref value);
long* longAddress = (long*)Unsafe.AsPointer(ref value); // Unsafe.AsPointer is safe since value is on stack
Byte4Short2 b4s2 = Unsafe.Read<Byte4Short2>(longAddress);
if (BitConverter.IsLittleEndian)
{
Expand Down Expand Up @@ -117,7 +117,7 @@ public static unsafe void ReadWriteDoublePointer()
{
int value1 = 10;
int value2 = 20;
int* valueAddress = (int*)Unsafe.AsPointer(ref value1);
int* valueAddress = (int*)Unsafe.AsPointer(ref value1); // Unsafe.AsPointer is safe since value1 is on stack
int** valueAddressPtr = &valueAddress;
Unsafe.Write(valueAddressPtr, new IntPtr(&value2));

Expand All @@ -132,7 +132,7 @@ public static unsafe void CopyToRef()
{
int value = 10;
int destination = -1;
Unsafe.Copy(ref destination, Unsafe.AsPointer(ref value));
Unsafe.Copy(ref destination, Unsafe.AsPointer(ref value)); // Unsafe.AsPointer is safe since value is on stack
Assert.Equal(10, destination);
Assert.Equal(10, value);

Expand All @@ -147,7 +147,7 @@ public static unsafe void CopyToVoidPtr()
{
int value = 10;
int destination = -1;
Unsafe.Copy(Unsafe.AsPointer(ref destination), ref value);
Unsafe.Copy(Unsafe.AsPointer(ref destination), ref value); // Unsafe.AsPointer is safe since destination is on stack
Assert.Equal(10, destination);
Assert.Equal(10, value);

Expand All @@ -163,7 +163,7 @@ public static unsafe void CopyToRefGenericStruct()
Int32Generic<string> destination = default;
Int32Generic<string> value = new() { Int32 = 5, Value = "a" };

Unsafe.Copy(ref destination, Unsafe.AsPointer(ref value));
Unsafe.Copy(ref destination, Unsafe.AsPointer(ref value)); // Unsafe.AsPointer is safe since value is on stack

Assert.Equal(5, destination.Int32);
Assert.Equal("a", destination.Value);
Expand All @@ -175,7 +175,7 @@ public static unsafe void CopyToVoidPtrGenericStruct()
Int32Generic<string> destination = default;
Int32Generic<string> value = new() { Int32 = 5, Value = "a" };

Unsafe.Copy(Unsafe.AsPointer(ref destination), ref value);
Unsafe.Copy(Unsafe.AsPointer(ref destination), ref value); // Unsafe.AsPointer is safe since destination is on stack

Assert.Equal(5, destination.Int32);
Assert.Equal("a", destination.Value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,9 @@ private unsafe T ReadBigEndian<T>() where T : struct
{
data.Reverse();
}
data.CopyTo(new Span<byte>(Unsafe.AsPointer(ref ret), data.Length));
#pragma warning disable CS8500 // takes address of managed type
data.CopyTo(new Span<byte>(&ret, data.Length));
hamarb123 marked this conversation as resolved.
Show resolved Hide resolved
#pragma warning restore CS8500
return ret;
}
}
Expand All @@ -546,7 +548,9 @@ public override void Write(string val)
private unsafe void WriteBigEndian<T>(T val) where T : struct
{
Span<byte> data = stackalloc byte[Unsafe.SizeOf<T>()];
new Span<byte>(Unsafe.AsPointer(ref val), data.Length).CopyTo(data);
#pragma warning disable CS8500 // takes address of managed type
new Span<byte>(&val, data.Length).CopyTo(data);
#pragma warning restore CS8500
if (BitConverter.IsLittleEndian)
{
data.Reverse();
Expand Down
2 changes: 1 addition & 1 deletion src/mono/sample/wasm/simple-raytracer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ private static void renderPixel (int i, int j, ref Vec3f light, Intersector inte
if (didHitZ && (hitZ > sphere.Center.z))
continue;

if (intersector.Intersect(ref pos, ref dir, Unsafe.AsPointer(ref sphere), ref intersection_normal)) {
if (intersector.Intersect(ref pos, ref dir, &sphere, ref intersection_normal)) {
sampleEnv(ref intersection_normal, ref color);

const float ambientScale = 0.2f;
Expand Down
6 changes: 4 additions & 2 deletions src/tests/JIT/Directed/debugging/poisoning/poison.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class Program
[Fact]
public static unsafe int TestEntryPoint()
{
#pragma warning disable CS8500 // takes address of managed type
bool result = true;

int poisoned;
Expand All @@ -16,7 +17,7 @@ public static unsafe int TestEntryPoint()

GCRef zeroed;
Unsafe.SkipInit(out zeroed);
result &= VerifyZero(Unsafe.AsPointer(ref zeroed), Unsafe.SizeOf<GCRef>());
result &= VerifyZero(&zeroed, sizeof(GCRef));

WithoutGCRef poisoned2;
Unsafe.SkipInit(out poisoned2);
Expand All @@ -36,9 +37,10 @@ public static unsafe int TestEntryPoint()

GCRef zeroed2;
Unsafe.SkipInit(out zeroed2);
result &= VerifyZero(Unsafe.AsPointer(ref zeroed2), Unsafe.SizeOf<GCRef>());
result &= VerifyZero(&zeroed2, sizeof(GCRef));

return result ? 100 : 101;
#pragma warning restore CS8500
}

[MethodImpl(MethodImplOptions.NoInlining)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public unsafe class Runtime_61510
[Fact]
public static int TestEntryPoint()
{
// Unsafe.AsPointer is safe since static field is marked with [FixedAddressValueType]
ref byte result = ref AddZeroByrefToNativeInt((nint)Unsafe.AsPointer(ref s_field));

return Unsafe.AreSame(ref s_field, ref result) ? 100 : 101;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public unsafe static void EntryPoint()
if (Sse2.IsSupported)
{
ulong value = 0;
Test((byte*)Unsafe.AsPointer(ref value));
Test((byte*)&value);
Assert.True(value == 246);
}
}
Expand Down
14 changes: 8 additions & 6 deletions src/tests/Loader/classloader/generics/Pointers/Pointers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,20 @@ public static void PointerArray()
[MethodImpl(MethodImplOptions.NoInlining)]
private static void PointerArrayImpl()
{
int*[] intPtrArray = new int*[5];
Span<int> intSpan = stackalloc int[intPtrArray.Length];
int* intArray = (int*)Unsafe.AsPointer(ref intSpan.GetPinnableReference());
int intAllocationSize = 5;
int*[] intPtrArray = new int*[intAllocationSize];
int* intArray = stackalloc int[intAllocationSize];
Span<int> intSpan = new Span<int>(intArray, intAllocationSize);
for (int i = 0; i < intPtrArray.Length; i++)
{
intArray[i] = i;
intPtrArray[i] = &intArray[i];
}

Struct*[] structPtrArray = new Struct*[5];
Span<Struct> structSpan = stackalloc Struct[structPtrArray.Length];
Struct* structArray = (Struct*)Unsafe.AsPointer(ref structSpan.GetPinnableReference());
int structAllocationSize = 5;
Struct*[] structPtrArray = new Struct*[structAllocationSize];
Struct* structArray = stackalloc Struct[structAllocationSize];
Span<Struct> structSpan = new Span<Struct>(structArray, structAllocationSize);
for (int i = 0; i < structPtrArray.Length; i++)
{
structArray[i] = new Struct() { Num = i };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,9 @@ public class UnmanagedByRef<T> : Base where T : struct, IGetValue
[MethodImpl(MethodImplOptions.NoInlining)]
public unsafe void TestAsPointer(T x)
{
IntPtr unsafeValuePtr = (IntPtr)Unsafe.AsPointer(ref x);
#pragma warning disable CS8500 // takes address of managed type
IntPtr unsafeValuePtr = (IntPtr)&x;
#pragma warning restore CS8500
GC.Collect();
GC.Collect();
GC.Collect();
Expand All @@ -487,6 +489,7 @@ public unsafe void TestGeneralFunction(T x)
[MethodImpl(MethodImplOptions.NoInlining)]
unsafe IntPtr someFuncWithByRefArgs(ref T x)
{
// Unsafe.AsPointer is safe since the reference is expected to be pinned
return (IntPtr)Unsafe.AsPointer(ref x);
}

Expand Down
Loading