Skip to content

Commit

Permalink
Annotate GetUninitializedObject (dotnet#37741)
Browse files Browse the repository at this point in the history
We don't have a good annotation for this so going with a superset. We could choose to intrinsify it in the linker to restrict this if necessary.
  • Loading branch information
MichalStrehovsky authored Jun 17, 2020
1 parent 8219c11 commit 1496ab3
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,14 @@ public static int OffsetToStringData
public static extern bool TryEnsureSufficientExecutionStack();

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object GetUninitializedObjectInternal(Type type);
private static extern object GetUninitializedObjectInternal(
// This API doesn't call any constructors, but the type needs to be seen as constructed.
// A type is seen as constructed if a constructor is kept.
// This obviously won't cover a type with no constructor. Reference types with no
// constructor are an academic problem. Valuetypes with no constructors are a problem,
// but IL Linker currently treats them as always implicitly boxed.
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
Type type);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern object AllocateUninitializedClone(object obj);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Reflection;
Expand Down Expand Up @@ -52,7 +53,14 @@ ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), offset),
}
}

public static object GetUninitializedObject(Type type)
public static object GetUninitializedObject(
// This API doesn't call any constructors, but the type needs to be seen as constructed.
// A type is seen as constructed if a constructor is kept.
// This obviously won't cover a type with no constructor. Reference types with no
// constructor are an academic problem. Valuetypes with no constructors are a problem,
// but IL Linker currently treats them as always implicitly boxed.
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
Type type)
{
if (type is null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
Expand Down Expand Up @@ -180,7 +181,14 @@ public static void CheckTypeSecurity(Type t, TypeFilterLevel securityLevel)
// nop
}

public static object GetUninitializedObject(Type type) => RuntimeHelpers.GetUninitializedObject(type);
public static object GetUninitializedObject(
// This API doesn't call any constructors, but the type needs to be seen as constructed.
// A type is seen as constructed if a constructor is kept.
// This obviously won't cover a type with no constructor. Reference types with no
// constructor are an academic problem. Valuetypes with no constructors are a problem,
// but IL Linker currently treats them as always implicitly boxed.
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
Type type) => RuntimeHelpers.GetUninitializedObject(type);

public static object GetSafeUninitializedObject(Type type) => RuntimeHelpers.GetUninitializedObject(type);

Expand Down

0 comments on commit 1496ab3

Please sign in to comment.