Don't block non-blittable pointer types in P/Invokes. (#1866)
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Thu, 23 Jan 2020 00:22:09 +0000 (16:22 -0800)
committerGitHub <noreply@github.com>
Thu, 23 Jan 2020 00:22:09 +0000 (16:22 -0800)
* Don't block non-blittable pointer types in P/Invokes.

Don't block non-blittable pointer types in P/Invokes. If you're using pointers in interop you're already using unsafe code so we're going to assume you know what you're doing. C# won't let you form a pointer to a reference, so there's no risk of passing an object reference directly to native unless you're writing IL directly.

Fixes dotnet/coreclr#27800

* Delete unused resources.

* Apply fix to managed type system as well.

* Add positive test for nonblittable pointers. Remove negative tests that were in GenericTest.

24 files changed:
src/coreclr/src/dlls/mscorrc/mscorrc.rc
src/coreclr/src/dlls/mscorrc/resource.h
src/coreclr/src/tools/Common/TypeSystem/Interop/IL/MarshalHelpers.cs
src/coreclr/src/vm/mlinfo.cpp
src/coreclr/tests/src/Interop/CMakeLists.txt
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.NullableB.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.NullableC.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.NullableD.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.NullableF.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.NullableL.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.NullableU.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.Point1B.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.Point1C.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.Point2B.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.Point2C.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.Point3B.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.Point3C.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.Point4B.cs
src/coreclr/tests/src/Interop/PInvoke/Generics/GenericsTest.Point4C.cs
src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/CMakeLists.txt [new file with mode: 0644]
src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/NonBlittablePointer.csproj [moved from src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/PInvokePointerTest.csproj with 75% similarity]
src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/NonBlittablePointerNative.cpp [new file with mode: 0644]
src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/PInvokePointerTest.cs [deleted file]
src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/Program.cs [new file with mode: 0644]

index 327a564..d57f248 100644 (file)
@@ -608,8 +608,6 @@ BEGIN
     IDS_EE_BADMARSHAL_SAFEHANDLEARRAY       "Invalid managed/unmanaged type combination (Arrays of SafeHandles are not supported)."
     IDS_EE_BADMARSHAL_CRITICALHANDLEARRAY   "Invalid managed/unmanaged type combination (Arrays of CriticalHandles are not supported)."
     IDS_EE_BADMARSHAL_SYSARRAY              "Invalid managed/unmanaged type combination (System.Array must be paired with SafeArray or Interface)."
-    IDS_EE_BADMARSHAL_PTRSUBTYPE            "Pointers cannot reference managed objects.  Use ByRef instead."
-    IDS_EE_BADMARSHAL_PTRNONBLITTABLE       "Pointers cannot reference marshaled structures.  Use ByRef instead."
     IDS_EE_BADMARSHAL_RESTRICTION           "This type can only be marshaled in restricted ways."
     IDS_EE_BADMARSHAL_ASANYRESTRICTION      "AsAny cannot be used on return types, ByRef parameters, ArrayWithOffset, or parameters passed from unmanaged to managed."
     IDS_EE_BADMARSHAL_VBBYVALSTRRESTRICTION "VBByRefStr can only be used in combination with in/out, ByRef managed-to-unmanaged strings."
index fe09f73..363f6e7 100644 (file)
 #define IDS_EE_BADMARSHAL_BADMANAGED            0x1756
 #define IDS_EE_SRC_OBJ_NOT_COMOBJECT            0x1757
 #define IDS_EE_CANNOT_COERCE_COMOBJECT          0x1759
-#define IDS_EE_BADMARSHAL_PTRSUBTYPE            0x175b
-#define IDS_EE_BADMARSHAL_PTRNONBLITTABLE       0x175c
 
 #define IDS_EE_BADMARSHAL_RESTRICTION           0x175d
 #define IDS_EE_BADMARSHAL_ASANYRESTRICTION      0x175f
index 96543a9..3febee8 100644 (file)
@@ -11,8 +11,8 @@ namespace Internal.TypeSystem.Interop
 {
     public static partial class MarshalHelpers
     {
-        internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type, 
-                MarshallerKind kind, 
+        internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type,
+                MarshallerKind kind,
                 MarshallerKind elementMarshallerKind,
 #if !READYTORUN
                 InteropStateManager interopStateManager,
@@ -121,7 +121,7 @@ namespace Internal.TypeSystem.Interop
 #if !READYTORUN
                             interopStateManager,
 #endif
-                            marshalAs, 
+                            marshalAs,
                             isArrayElement: true);
 
                         return elementNativeType.MakePointerType();
@@ -438,22 +438,6 @@ namespace Internal.TypeSystem.Interop
             }
             else if (type.IsPointer)
             {
-#if READYTORUN
-                TypeDesc parameterType = ((PointerType)type).ParameterType;
-
-                if ((!parameterType.IsEnum
-                    && !parameterType.IsPrimitive
-                    && !MarshalUtils.IsBlittableType(parameterType))
-                    || parameterType.IsGCPointer)
-                {
-                    // Pointers cannot reference marshaled structures.  Use ByRef instead.
-                    return MarshallerKind.Invalid;
-                }
-#else
-                // Do not bother enforcing the above artificial restriction
-                // See https://github.com/dotnet/coreclr/issues/27800
-#endif
-
                 if (nativeType == NativeTypeKind.Default)
                     return MarshallerKind.BlittableValue;
                 else
index efc9169..de08673 100644 (file)
@@ -1612,13 +1612,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
                 // plus they are not marked as blittable.
                 if (!th.IsEnum())
                 {
-                    // It should be blittable
-                    if (!th.IsBlittable())
-                    {
-                        m_resID = IDS_EE_BADMARSHAL_PTRNONBLITTABLE;
-                        IfFailGoto(E_FAIL, lFail);
-                    }
-
                     // Check for Copy Constructor Modifier
                     if (sigtmp.HasCustomModifier(pModule, "Microsoft.VisualC.NeedsCopyConstructorModifier", ELEMENT_TYPE_CMOD_REQD) ||
                         sigtmp.HasCustomModifier(pModule, "System.Runtime.CompilerServices.IsCopyConstructed", ELEMENT_TYPE_CMOD_REQD) )
@@ -1634,17 +1627,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
                     }
                 }
             }
-            else
-            {
-                if (!(mtype2 != ELEMENT_TYPE_CLASS &&
-                    mtype2 != ELEMENT_TYPE_STRING &&
-                    mtype2 != ELEMENT_TYPE_OBJECT &&
-                    mtype2 != ELEMENT_TYPE_SZARRAY))
-                {
-                    m_resID = IDS_EE_BADMARSHAL_PTRSUBTYPE;
-                    IfFailGoto(E_FAIL, lFail);
-                }
-            }
         }
     }
 
index 4fe2e6e..a111f46 100644 (file)
@@ -20,6 +20,7 @@ add_subdirectory(PInvoke/BestFitMapping/LPStr)
 add_subdirectory(PInvoke/Delegate)
 add_subdirectory(PInvoke/Primitives/Int)
 add_subdirectory(PInvoke/Primitives/RuntimeHandles)
+add_subdirectory(PInvoke/Primitives/Pointer)
 add_subdirectory(PInvoke/SizeParamIndex/PInvoke/PassingByOut)
 add_subdirectory(PInvoke/SizeParamIndex/PInvoke/PassingByRef)
 add_subdirectory(PInvoke/SizeParamIndex/ReversePInvoke/PassingByOut)
index 61580bb..edff74a 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern bool? GetNullableB(bool hasValue, bool value);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetNullableBOut(bool hasValue, bool value, bool?* pValue);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetNullableBOut(bool hasValue, bool value, out bool? pValue);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern bool?* GetNullableBPtr(bool hasValue, bool value);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetNullableBPtr")]
     public static extern ref readonly bool? GetNullableBRef(bool hasValue, bool value);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern bool? AddNullableB(bool? lhs, bool? rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern bool? AddNullableBs(bool?* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern bool? AddNullableBs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] bool?[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,17 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableB(true, false));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            bool? value2;
-            GenericsNative.GetNullableBOut(true, false, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableBOut(true, false, out bool? value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableBPtr(true, false));
-
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableBRef(true, false));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableB(default, default));
 
         bool?[] values = new bool?[] {
@@ -63,13 +45,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (bool?* pValues = &values[0])
-            {
-                GenericsNative.AddNullableBs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableBs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableBs(in values[0], values.Length));
index c2a33ef..73a5e8e 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern char? GetNullableC(bool hasValue, char value);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetNullableCOut(bool hasValue, char value, char?* pValue);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetNullableCOut(bool hasValue, char value, out char? pValue);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern char?* GetNullableCPtr(bool hasValue, char value);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetNullableCPtr")]
     public static extern ref readonly char? GetNullableCRef(bool hasValue, char value);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern char? AddNullableC(char? lhs, char? rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern char? AddNullableCs(char?* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern char? AddNullableCs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] char?[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,17 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableC(true, '1'));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            char? value2;
-            GenericsNative.GetNullableCOut(true, '1', &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableCOut(true, '1', out char? value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableCPtr(true, '1'));
-
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableCRef(true, '1'));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableC(default, default));
 
         char?[] values = new char?[] {
@@ -63,13 +45,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (char?* pValues = &values[0])
-            {
-                GenericsNative.AddNullableCs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableCs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableCs(in values[0], values.Length));
index 7bf829d..cc21ebd 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern double? GetNullableD(bool hasValue, double value);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetNullableDOut(bool hasValue, double value, double?* pValue);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetNullableDOut(bool hasValue, double value, out double? pValue);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern double?* GetNullableDPtr(bool hasValue, double value);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetNullableDPtr")]
     public static extern ref readonly double? GetNullableDRef(bool hasValue, double value);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern double? AddNullableD(double? lhs, double? rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern double? AddNullableDs(double?* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern double? AddNullableDs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] double?[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,17 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableD(true, 1.0));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            double? value2;
-            GenericsNative.GetNullableDOut(true, 1.0, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableDOut(true, 1.0, out double? value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableDPtr(true, 1.0));
-
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableDRef(true, 1.0));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableD(default, default));
 
         double?[] values = new double?[] {
@@ -63,13 +45,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (double?* pValues = &values[0])
-            {
-                GenericsNative.AddNullableDs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableDs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableDs(in values[0], values.Length));
index c0f2f69..9d3b6b1 100644 (file)
@@ -10,16 +10,9 @@ unsafe partial class GenericsNative
 {
     [DllImport(nameof(GenericsNative))]
     public static extern float? GetNullableF(bool hasValue, float value);
-
-    [DllImport(nameof(GenericsNative))]
-    public static extern void GetNullableFOut(bool hasValue, float value, float?* pValue);
-
     [DllImport(nameof(GenericsNative))]
     public static extern void GetNullableFOut(bool hasValue, float value, out float? pValue);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern float?* GetNullableFPtr(bool hasValue, float value);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetNullableFPtr")]
     public static extern ref readonly float? GetNullableFRef(bool hasValue, float value);
 
@@ -27,9 +20,6 @@ unsafe partial class GenericsNative
     public static extern float? AddNullableF(float? lhs, float? rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern float? AddNullableFs(float?* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern float? AddNullableFs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] float?[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,17 +32,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableF(true, 1.0f));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            float? value2;
-            GenericsNative.GetNullableFOut(true, 1.0f, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableFOut(true, 1.0f, out float? value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableFPtr(true, 1.0f));
-
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableFRef(true, 1.0f));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableF(default, default));
 
         float?[] values = new float?[] {
@@ -63,13 +44,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (float?* pValues = &values[0])
-            {
-                GenericsNative.AddNullableFs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableFs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableFs(in values[0], values.Length));
index 21255d6..a85d2e4 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern long? GetNullableL(bool hasValue, long value);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetNullableLOut(bool hasValue, long value, long?* pValue);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetNullableLOut(bool hasValue, long value, out long? pValue);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern long?* GetNullableLPtr(bool hasValue, long value);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetNullableLPtr")]
     public static extern ref readonly long? GetNullableLRef(bool hasValue, long value);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern long? AddNullableL(long? lhs, long? rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern long? AddNullableLs(long?* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern long? AddNullableLs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] long?[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,17 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableL(true, 1L));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            long? value2;
-            GenericsNative.GetNullableLOut(true, 1L, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableLOut(true, 1L, out long? value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableLPtr(true, 1L));
-
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableLRef(true, 1L));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableL(default, default));
 
         long?[] values = new long?[] {
@@ -63,13 +45,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (long?* pValues = &values[0])
-            {
-                GenericsNative.AddNullableLs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableLs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableLs(in values[0], values.Length));
index cba3a45..331b454 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern uint? GetNullableU(bool hasValue, uint value);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetNullableUOut(bool hasValue, uint value, uint?* pValue);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetNullableUOut(bool hasValue, uint value, out uint? pValue);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern uint?* GetNullableUPtr(bool hasValue, uint value);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetNullableUPtr")]
     public static extern ref readonly uint? GetNullableURef(bool hasValue, uint value);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern uint? AddNullableU(uint? lhs, uint? rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern uint? AddNullableUs(uint?* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern uint? AddNullableUs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] uint?[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,17 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableU(true, 1u));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            uint? value2;
-            GenericsNative.GetNullableUOut(true, 1u, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableUOut(true, 1u, out uint? value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableUPtr(true, 1u));
-
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetNullableURef(true, 1u));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableU(default, default));
 
         uint?[] values = new uint?[] {
@@ -63,13 +45,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (uint?* pValues = &values[0])
-            {
-                GenericsNative.AddNullableUs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableUs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddNullableUs(in values[0], values.Length));
index 24a3ab7..6dea4b4 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern Point1<bool> GetPoint1B(bool e00);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetPoint1BOut(bool e00, Point1<bool>* value);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetPoint1BOut(bool e00, out Point1<bool> value);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern Point1<bool>* GetPoint1BPtr(bool e00);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetPoint1BPtr")]
     public static extern ref readonly Point1<bool> GetPoint1BRef(bool e00);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern Point1<bool> AddPoint1B(Point1<bool> lhs, Point1<bool> rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern Point1<bool> AddPoint1Bs(Point1<bool>* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern Point1<bool> AddPoint1Bs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point1<bool>[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,15 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1B(true));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            GenericsNative.Point1<bool> value2;
-            GenericsNative.GetPoint1BOut(true, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1BOut(true, out GenericsNative.Point1<bool> value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1BPtr(true));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1BRef(true));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1B(default, default));
@@ -63,13 +47,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (GenericsNative.Point1<bool>* pValues = &values[0])
-            {
-                GenericsNative.AddPoint1Bs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1Bs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1Bs(in values[0], values.Length));
index 1f744d6..2161632 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern Point1<char> GetPoint1C(char e00);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetPoint1COut(char e00, Point1<char>* value);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetPoint1COut(char e00, out Point1<char> value);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern Point1<char>* GetPoint1CPtr(char e00);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetPoint1CPtr")]
     public static extern ref readonly Point1<char> GetPoint1CRef(char e00);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern Point1<char> AddPoint1C(Point1<char> lhs, Point1<char> rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern Point1<char> AddPoint1Cs(Point1<char>* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern Point1<char> AddPoint1Cs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point1<char>[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,15 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1C('1'));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            GenericsNative.Point1<char> value2;
-            GenericsNative.GetPoint1COut('1', &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1COut('1', out GenericsNative.Point1<char> value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1CPtr('1'));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint1CRef('1'));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1C(default, default));
@@ -63,13 +47,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (GenericsNative.Point1<char>* pValues = &values[0])
-            {
-                GenericsNative.AddPoint1Cs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1Cs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint1Cs(in values[0], values.Length));
index d484b99..ce5747c 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern Point2<bool> GetPoint2B(bool e00, bool e01);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetPoint2BOut(bool e00, bool e01, Point2<bool>* value);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetPoint2BOut(bool e00, bool e01, out Point2<bool> value);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern Point2<bool>* GetPoint2BPtr(bool e00, bool e01);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetPoint2BPtr")]
     public static extern ref readonly Point2<bool> GetPoint2BRef(bool e00, bool e01);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern Point2<bool> AddPoint2B(Point2<bool> lhs, Point2<bool> rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern Point2<bool> AddPoint2Bs(Point2<bool>* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern Point2<bool> AddPoint2Bs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point2<bool>[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,15 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2B(true, false));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            GenericsNative.Point2<bool> value2;
-            GenericsNative.GetPoint2BOut(true, false, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2BOut(true, false, out GenericsNative.Point2<bool> value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2BPtr(true, false));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2BRef(true, false));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2B(default, default));
@@ -63,12 +47,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (GenericsNative.Point2<bool>* pValues = &values[0])
-            {
-                GenericsNative.AddPoint2Bs(pValues, values.Length);
-            }
-        });
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2Bs(values, values.Length));
 
index 35bed81..b2a3338 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern Point2<char> GetPoint2C(char e00, char e01);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetPoint2COut(char e00, char e01, Point2<char>* value);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetPoint2COut(char e00, char e01, out Point2<char> value);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern Point2<char>* GetPoint2CPtr(char e00, char e01);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetPoint2CPtr")]
     public static extern ref readonly Point2<char> GetPoint2CRef(char e00, char e01);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern Point2<char> AddPoint2C(Point2<char> lhs, Point2<char> rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern Point2<char> AddPoint2Cs(Point2<char>* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern Point2<char> AddPoint2Cs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point2<char>[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,15 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2C('1', '2'));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            GenericsNative.Point2<char> value2;
-            GenericsNative.GetPoint2COut('1', '2', &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2COut('1', '2', out GenericsNative.Point2<char> value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2CPtr('1', '2'));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint2CRef('1', '2'));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2C(default, default));
@@ -63,13 +47,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (GenericsNative.Point2<char>* pValues = &values[0])
-            {
-                GenericsNative.AddPoint2Cs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2Cs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint2Cs(in values[0], values.Length));
index 4cec3be..9903b3a 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern Point3<bool> GetPoint3B(bool e00, bool e01, bool e02);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetPoint3BOut(bool e00, bool e01, bool e02, Point3<bool>* value);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetPoint3BOut(bool e00, bool e01, bool e02, out Point3<bool> value);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern Point3<bool>* GetPoint3BPtr(bool e00, bool e01, bool e02);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetPoint3BPtr")]
     public static extern ref readonly Point3<bool> GetPoint3BRef(bool e00, bool e01, bool e02);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern Point3<bool> AddPoint3B(Point3<bool> lhs, Point3<bool> rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern Point3<bool> AddPoint3Bs(Point3<bool>* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern Point3<bool> AddPoint3Bs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point3<bool>[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,15 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3B(true, false, true));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            GenericsNative.Point3<bool> value2;
-            GenericsNative.GetPoint3BOut(true, false, true, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3BOut(true, false, true, out GenericsNative.Point3<bool> value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3BPtr(true, false, true));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3BRef(true, false, true));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3B(default, default));
@@ -63,13 +47,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (GenericsNative.Point3<bool>* pValues = &values[0])
-            {
-                GenericsNative.AddPoint3Bs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3Bs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3Bs(in values[0], values.Length));
index f461443..d823a6c 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern Point3<char> GetPoint3C(char e00, char e01, char e02);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetPoint3COut(char e00, char e01, char e02, Point3<char>* value);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetPoint3COut(char e00, char e01, char e02, out Point3<char> value);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern Point3<char>* GetPoint3CPtr(char e00, char e01, char e02);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetPoint3CPtr")]
     public static extern ref readonly Point3<char> GetPoint3CRef(char e00, char e01, char e02);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern Point3<char> AddPoint3C(Point3<char> lhs, Point3<char> rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern Point3<char> AddPoint3Cs(Point3<char>* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern Point3<char> AddPoint3Cs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point3<char>[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,15 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3C('1', '2', '3'));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            GenericsNative.Point3<char> value2;
-            GenericsNative.GetPoint3COut('1', '2', '3', &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3COut('1', '2', '3', out GenericsNative.Point3<char> value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3CPtr('1', '2', '3'));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint3CRef('1', '2', '3'));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3C(default, default));
@@ -63,13 +47,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (GenericsNative.Point3<char>* pValues = &values[0])
-            {
-                GenericsNative.AddPoint3Cs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3Cs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint3Cs(in values[0], values.Length));
index e66be24..9336895 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern Point4<bool> GetPoint4B(bool e00, bool e01, bool e02, bool e03);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetPoint4BOut(bool e00, bool e01, bool e02, bool e03, Point4<bool>* value);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetPoint4BOut(bool e00, bool e01, bool e02, bool e03, out Point4<bool> value);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern Point4<bool>* GetPoint4BPtr(bool e00, bool e01, bool e02, bool e03);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetPoint4BPtr")]
     public static extern ref readonly Point4<bool> GetPoint4BRef(bool e00, bool e01, bool e02, bool e03);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern Point4<bool> AddPoint4B(Point4<bool> lhs, Point4<bool> rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern Point4<bool> AddPoint4Bs(Point4<bool>* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern Point4<bool> AddPoint4Bs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point4<bool>[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,15 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4B(true, false, true, false));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            GenericsNative.Point4<bool> value2;
-            GenericsNative.GetPoint4BOut(true, false, true, false, &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4BOut(true, false, true, false, out GenericsNative.Point4<bool> value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4BPtr(true, false, true, false));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4BRef(true, false, true, false));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4B(default, default));
@@ -63,13 +47,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (GenericsNative.Point4<bool>* pValues = &values[0])
-            {
-                GenericsNative.AddPoint4Bs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4Bs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4Bs(in values[0], values.Length));
index 7c9d297..4d01453 100644 (file)
@@ -12,14 +12,8 @@ unsafe partial class GenericsNative
     public static extern Point4<char> GetPoint4C(char e00, char e01, char e02, char e03);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern void GetPoint4COut(char e00, char e01, char e02, char e03, Point4<char>* value);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern void GetPoint4COut(char e00, char e01, char e02, char e03, out Point4<char> value);
 
-    [DllImport(nameof(GenericsNative))]
-    public static extern Point4<char>* GetPoint4CPtr(char e00, char e01, char e02, char e03);
-
     [DllImport(nameof(GenericsNative), EntryPoint = "GetPoint4CPtr")]
     public static extern ref readonly Point4<char> GetPoint4CRef(char e00, char e01, char e02, char e03);
 
@@ -27,9 +21,6 @@ unsafe partial class GenericsNative
     public static extern Point4<char> AddPoint4C(Point4<char> lhs, Point4<char> rhs);
 
     [DllImport(nameof(GenericsNative))]
-    public static extern Point4<char> AddPoint4Cs(Point4<char>* pValues, int count);
-
-    [DllImport(nameof(GenericsNative))]
     public static extern Point4<char> AddPoint4Cs([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] Point4<char>[] pValues, int count);
 
     [DllImport(nameof(GenericsNative))]
@@ -42,15 +33,8 @@ unsafe partial class GenericsTest
     {
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4C('1', '2', '3', '4'));
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            GenericsNative.Point4<char> value2;
-            GenericsNative.GetPoint4COut('1', '2', '3', '4', &value2);
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4COut('1', '2', '3', '4', out GenericsNative.Point4<char> value3));
 
-        Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4CPtr('1', '2', '3', '4'));
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.GetPoint4CRef('1', '2', '3', '4'));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4C(default, default));
@@ -63,13 +47,6 @@ unsafe partial class GenericsTest
             default
         };
 
-        Assert.Throws<MarshalDirectiveException>(() => {
-            fixed (GenericsNative.Point4<char>* pValues = &values[0])
-            {
-                GenericsNative.AddPoint4Cs(pValues, values.Length);
-            }
-        });
-
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4Cs(values, values.Length));
 
         Assert.Throws<MarshalDirectiveException>(() => GenericsNative.AddPoint4Cs(in values[0], values.Length));
diff --git a/src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/CMakeLists.txt b/src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ca190ec
--- /dev/null
@@ -0,0 +1,6 @@
+include ("${CLR_INTEROP_TEST_ROOT}/Interop.cmake")
+set(SOURCES
+    NonBlittablePointerNative.cpp
+)
+add_library (NonBlittablePointerNative SHARED ${SOURCES})
+install (TARGETS NonBlittablePointerNative DESTINATION bin)
@@ -1,10 +1,14 @@
 <Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
+
   <ItemGroup>
-    <Compile Include="PInvokePointerTest.cs" />
+    <Compile Include="Program.cs" />
+    <ProjectReference Include="CMakeLists.txt" />
   </ItemGroup>
+
   <Import Project="$([MSBuild]::GetPathOfFileAbove(Interop.settings.targets))" />
 </Project>
diff --git a/src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/NonBlittablePointerNative.cpp b/src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/NonBlittablePointerNative.cpp
new file mode 100644 (file)
index 0000000..b4b9075
--- /dev/null
@@ -0,0 +1,10 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include <xplatform.h>
+
+extern "C" DLL_EXPORT void STDMETHODCALLTYPE Negate(bool* ptr)
+{
+    *ptr = !*ptr;
+}
diff --git a/src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/PInvokePointerTest.cs b/src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/PInvokePointerTest.cs
deleted file mode 100644 (file)
index 1080e0b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// 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;
-using System.Runtime.InteropServices;
-using TestLibrary;
-
-unsafe class Program
-{
-    [StructLayout(LayoutKind.Sequential)]
-    struct NonBlittable
-    {
-        bool _nonBlittable;
-    }
-
-    // the "string unused" parameter is just so that we don't hit https://github.com/dotnet/coreclr/issues/27408 that
-    // makes this p/invoke actually work.
-    [DllImport("Unused")]
-    private static extern void PointerToNonBlittableType(NonBlittable* pNonBlittable, string unused);
-
-    static int Main()
-    {
-        Assert.Throws<MarshalDirectiveException>(() => PointerToNonBlittableType(null, null));
-
-        return 100;
-    }
-}
diff --git a/src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/Program.cs b/src/coreclr/tests/src/Interop/PInvoke/Primitives/Pointer/Program.cs
new file mode 100644 (file)
index 0000000..d0d1d80
--- /dev/null
@@ -0,0 +1,25 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// 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;
+using System.Runtime.InteropServices;
+
+namespace NonBlittablePointer
+{
+    static class NonBlittablePointerNative
+    {
+        [DllImport(nameof(NonBlittablePointerNative))]
+        public static unsafe extern void Negate(bool* ptr);
+    }
+
+    class Program
+    {
+        static unsafe int Main(string[] args)
+        {
+            bool value = true;
+            NonBlittablePointerNative.Negate(&value);
+            return value == false ? 100 : 101;
+        }
+    }
+}