From dbd1955cb05a486a19d1d4eeccf9833afb2b30ed Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Thu, 2 Dec 2021 20:43:53 -0800 Subject: [PATCH 1/2] Revert "[Mono] Fix support for nested structs with explicit layout (#61467)" This reverts commit 64d127653b6100174d80ac36c89f660de224a6da. --- src/mono/mono/metadata/class-init.c | 104 ++++-------------- .../explicitlayout/NestedStructs/case01.cs | 74 ------------- .../NestedStructs/case01.csproj | 9 -- .../explicitlayout/NestedStructs/case02.cs | 89 --------------- .../NestedStructs/case02.csproj | 9 -- .../explicitlayout/NestedStructs/case03.cs | 62 ----------- .../NestedStructs/case03.csproj | 9 -- .../explicitlayout/NestedStructs/case04.cs | 62 ----------- .../NestedStructs/case04.csproj | 9 -- .../explicitlayout/NestedStructs/case05.cs | 52 --------- .../NestedStructs/case05.csproj | 9 -- .../explicitlayout/misc/array_segment.cs | 57 ---------- .../explicitlayout/misc/array_segment.csproj | 8 -- 13 files changed, 21 insertions(+), 532 deletions(-) delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.cs delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.csproj delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.cs delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.csproj delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.cs delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.csproj delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case04.cs delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case04.csproj delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case05.cs delete mode 100644 src/tests/Loader/classloader/explicitlayout/NestedStructs/case05.csproj delete mode 100644 src/tests/Loader/classloader/explicitlayout/misc/array_segment.cs delete mode 100644 src/tests/Loader/classloader/explicitlayout/misc/array_segment.csproj diff --git a/src/mono/mono/metadata/class-init.c b/src/mono/mono/metadata/class-init.c index c53f4e5fe0b725..86eadc64a11935 100644 --- a/src/mono/mono/metadata/class-init.c +++ b/src/mono/mono/metadata/class-init.c @@ -1864,85 +1864,6 @@ mono_class_is_gparam_with_nonblittable_parent (MonoClass *klass) return parent_class != mono_defaults.object_class; } -/** - * Checks if there are any overlapping object and non-object fields. - * The alignment of object reference fields is checked elswhere and this function assumes - * that all references are aligned correctly. - * - * \param layout_check A buffer to check which bytes hold object references or values - * \param klass Checked struct - * \param field_offsets Offsets of the klass' fields relative to the start of layout_check - * \param field_count Count of klass fields - * \param invalid_field_offset When the layout is invalid it will be set to the offset of the field which is invalid - * - * \return True if the layout of the struct is valid, otherwise false. - */ -static gboolean -validate_struct_fields_overlaps (guint8 *layout_check, int layout_size, MonoClass *klass, const int *field_offsets, const int field_count, int *invalid_field_offset) -{ - MonoClassField *field; - MonoType *ftype; - int field_offset; - - for (int i = 0; i < field_count && !mono_class_has_failure (klass); i++) { - // using mono_class_get_fields_internal isn't appropriate here because it will - // try to call mono_class_setup_fields which is what we're doing already - field = &m_class_get_fields (klass) [i]; - field_offset = field_offsets [i]; - - if (!field) - continue; - if (mono_field_is_deleted (field)) - continue; - if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) - continue; - - ftype = mono_type_get_underlying_type (field->type); - ftype = mono_type_get_basic_type_from_generic (ftype); - - if (mono_type_is_struct (ftype)) { - // recursively check the layout of the embedded struct - MonoClass *embedded_class = mono_class_from_mono_type_internal (ftype); - g_assert (m_class_is_fields_inited (embedded_class)); - - const int embedded_fields_count = mono_class_get_field_count (embedded_class); - int *embedded_offsets = g_new0 (int, embedded_fields_count); - for (int j = 0; j < embedded_fields_count; ++j) { - embedded_offsets [j] = field_offset + m_class_get_fields (embedded_class) [j].offset - MONO_ABI_SIZEOF (MonoObject); - } - - gboolean is_valid = validate_struct_fields_overlaps (layout_check, layout_size, embedded_class, embedded_offsets, embedded_fields_count, invalid_field_offset); - g_free (embedded_offsets); - - if (!is_valid) { - // overwrite whatever was in the invalid_field_offset with the offset of the currently checked field - // we want to return the outer most invalid field - *invalid_field_offset = field_offset; - return FALSE; - } - } else { - int align = 0; - int size = mono_type_size (field->type, &align); - guint8 type = type_has_references (klass, ftype) ? 1 : 2; - - // Mark the bytes used by this fields type based on if it contains references or not. - // Make sure there are no overlaps between object and non-object fields. - for (int j = 0; j < size; j++) { - int checked_byte = field_offset + j; - g_assert(checked_byte < layout_size); - - if (layout_check [checked_byte] != 0 && layout_check [checked_byte] != type) { - *invalid_field_offset = field_offset; - return FALSE; - } - layout_check [checked_byte] = type; - } - } - } - - return TRUE; -} - /* * mono_class_layout_fields: * @class: a class @@ -2233,12 +2154,29 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_ } /* check for incorrectly aligned or overlapped by a non-object field */ - guint8 *layout_check; + guint8 *layout_check; if (has_references) { layout_check = g_new0 (guint8, real_size); - int invalid_field_offset; - if (!validate_struct_fields_overlaps (layout_check, real_size, klass, field_offsets, top, &invalid_field_offset)) { - mono_class_set_type_load_failure (klass, "Could not load type '%s' because it contains an object field at offset %d that is incorrectly aligned or overlapped by a non-object field.", klass->name, invalid_field_offset); + for (i = 0; i < top && !mono_class_has_failure (klass); i++) { + field = &klass->fields [i]; + if (!field) + continue; + if (mono_field_is_deleted (field)) + continue; + if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) + continue; + int align = 0; + int size = mono_type_size (field->type, &align); + MonoType *ftype = mono_type_get_underlying_type (field->type); + ftype = mono_type_get_basic_type_from_generic (ftype); + guint8 type = type_has_references (klass, ftype) ? 1 : 2; + for (int j = 0; j < size; j++) { + if (layout_check [field_offsets [i] + j] != 0 && layout_check [field_offsets [i] + j] != type) { + mono_class_set_type_load_failure (klass, "Could not load type '%s' because it contains an object field at offset %d that is incorrectly aligned or overlapped by a non-object field.", klass->name, field->offset); + break; + } + layout_check [field_offsets [i] + j] = type; + } } g_free (layout_check); } diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.cs b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.cs deleted file mode 100644 index eb86c197bc22c9..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.cs +++ /dev/null @@ -1,74 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -[StructLayout(LayoutKind.Explicit, Size = 24)] -public struct ComplexStruct -{ - [FieldOffset(0)] - public object? Object; - - [FieldOffset(0)] - public InnerStruct Inner; - - [FieldOffset(8)] - public double Double; - - [FieldOffset(8)] - public ulong High; - - [FieldOffset(16)] - public ulong Low; -} - -[StructLayout(LayoutKind.Explicit, Size = 16)] -public struct InnerStruct -{ - [FieldOffset(0)] - public object? Object; - - [FieldOffset(8)] - public int High; - - [FieldOffset(12)] - public int Low; -} - -public class Test_NestedStructsWithExplicitLayout_Case01 { - private ComplexStruct currentCount = default; - - private void IncrementCount() - { - var x = new ComplexStruct(); - x.Inner.High = currentCount.Inner.High + 1; - currentCount = x; - } - - public static int Main () - { - try - { - var instance = new Test_NestedStructsWithExplicitLayout_Case01(); - instance.IncrementCount(); - var result = 99 + instance.currentCount.Inner.High; - - if (result == 100) - { - Console.WriteLine("PASS: union of Explict + Explicit works correctly"); - } - - return result; - } - catch (TypeLoadException e) - { - Console.WriteLine("FAIL: type was not loaded"); - return 101; - } - catch (Exception e) - { - return 102; - } - } -} diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.csproj b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.csproj deleted file mode 100644 index 1c3478d7dacfa9..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - Exe - enable - - - - - diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.cs b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.cs deleted file mode 100644 index 0f9926dce9aa6a..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -[StructLayout(LayoutKind.Explicit, Size = 16)] -public struct FirstLevel -{ - [FieldOffset(0)] - public object? Object; - - [FieldOffset(0)] - public SecondLevel SecondLevel; - - [FieldOffset(8)] - public int High; - - [FieldOffset(12)] - public int Low; -} - -[StructLayout(LayoutKind.Explicit, Size = 16)] -public struct SecondLevel -{ - [FieldOffset(0)] - public object? Object; - - [FieldOffset(0)] - public ThirdLevel ThirdLevel; - - [FieldOffset(8)] - public int High; - - [FieldOffset(12)] - public int Low; -} - -[StructLayout(LayoutKind.Explicit, Size = 16)] -public struct ThirdLevel -{ - [FieldOffset(0)] - public object? Object; - - [FieldOffset(8)] - public int High; - - [FieldOffset(12)] - public int Low; -} - -public class Test_NestedStructsWithExplicitLayout_Case02 { - private int Run(int value) - { - var x = new FirstLevel(); - x.Low = value; - return x.SecondLevel.ThirdLevel.Low; - } - - public static int Main () - { - try - { - var expectedResult = 13; - - var testInstance = new Test_NestedStructsWithExplicitLayout_Case02(); - var result = testInstance.Run(expectedResult); - - if (result == expectedResult) - { - Console.WriteLine("PASS: types were loaded correctly"); - return 100; - } - - Console.WriteLine("FAIL: invalid value"); - return 103; - } - catch (TypeLoadException e) - { - Console.WriteLine("FAIL: type was not loaded correctly"); - return 101; - } - catch (Exception e) - { - Console.WriteLine("FAIL: unknown error"); - return 102; - } - } -} diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.csproj b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.csproj deleted file mode 100644 index 7ab33ecb6cfb49..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - Exe - enable - - - - - diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.cs b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.cs deleted file mode 100644 index 57fd85be498e4e..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -[StructLayout(LayoutKind.Explicit)] -public struct FirstLevel -{ - [FieldOffset(0)] - public object? ConflictingObjectField; - - [FieldOffset(0)] - public SecondLevel SecondLevel; -} - -[StructLayout(LayoutKind.Explicit)] -public struct SecondLevel -{ - [FieldOffset(0)] - public ThirdLevel ThirdLevel; - - [FieldOffset(8)] - public long Value; -} - -[StructLayout(LayoutKind.Explicit)] -public struct ThirdLevel -{ - [FieldOffset(0)] - public long ConflictingValueTypeField; -} - -public class Test_NestedStructsWithExplicitLayout_Case06 { - private void Run() - { - var x = new FirstLevel(); - x.ConflictingObjectField = new object(); - } - - public static int Main () - { - try - { - var test = new Test_NestedStructsWithExplicitLayout_Case06(); - test.Run(); - } - catch (TypeLoadException e) - { - Console.WriteLine("PASS: object and non-object field overlap was detected"); - return 100; - } - catch (Exception e) - { - Console.WriteLine("FAIL: unexpected exception type"); - return 102; - } - - Console.WriteLine("FAIL: object and non-object field overlap was not detected"); - return 101; - } -} diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.csproj b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.csproj deleted file mode 100644 index 7308df24c65b72..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - Exe - enable - - - - - diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case04.cs b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case04.cs deleted file mode 100644 index 7e2cfc44758603..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case04.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -[StructLayout(LayoutKind.Explicit)] -public struct FirstLevel -{ - [FieldOffset(0)] - public object? ConflictingObjectField; - - [FieldOffset(0)] - public SecondLevel SecondLevel; -} - -[StructLayout(LayoutKind.Explicit)] -public struct SecondLevel -{ - [FieldOffset(0)] - public ThirdLevel ThirdLevel; - - [FieldOffset(8)] - public long Value; -} - -[StructLayout(LayoutKind.Explicit)] -public struct ThirdLevel -{ - [FieldOffset(6)] - public short ConflictingValueTypeField; -} - -public class Test_NestedStructsWithExplicitLayout_Case07 { - private void Run() - { - var x = new FirstLevel(); - x.ConflictingObjectField = new object(); - } - - public static int Main () - { - try - { - var test = new Test_NestedStructsWithExplicitLayout_Case07(); - test.Run(); - } - catch (TypeLoadException e) - { - Console.WriteLine("PASS: object and non-object field overlap was detected"); - return 100; - } - catch (Exception e) - { - Console.WriteLine("FAIL: unexpected exception type"); - return 102; - } - - Console.WriteLine("FAIL: object and non-object field overlap was not detected"); - return 101; - } -} diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case04.csproj b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case04.csproj deleted file mode 100644 index 6b6ec60a598c27..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case04.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - Exe - enable - - - - - diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case05.cs b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case05.cs deleted file mode 100644 index 9a4d8de050c7da..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case05.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -[StructLayout(LayoutKind.Explicit)] -public struct FirstLevel -{ - [FieldOffset(0)] - public object? ConflictingObjectField; - - [FieldOffset(0)] - public SecondLevel SecondLevel; -} - -[StructLayout(LayoutKind.Explicit)] -public struct SecondLevel -{ - [FieldOffset(0)] - public long ConflictingValueTypeField; -} - -public class Test_NestedStructsWithExplicitLayout_Case05 { - private void Run() - { - var x = new FirstLevel(); - x.ConflictingObjectField = new object(); - } - - public static int Main () - { - try - { - var test = new Test_NestedStructsWithExplicitLayout_Case05(); - test.Run(); - } - catch (TypeLoadException e) - { - Console.WriteLine("PASS: object and non-object field overlap was detected"); - return 100; - } - catch (Exception e) - { - Console.WriteLine("FAIL: unexpected exception type"); - return 102; - } - - Console.WriteLine("FAIL: object and non-object field overlap was not detected"); - return 101; - } -} diff --git a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case05.csproj b/src/tests/Loader/classloader/explicitlayout/NestedStructs/case05.csproj deleted file mode 100644 index e84314924ecab0..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/NestedStructs/case05.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - Exe - enable - - - - - diff --git a/src/tests/Loader/classloader/explicitlayout/misc/array_segment.cs b/src/tests/Loader/classloader/explicitlayout/misc/array_segment.cs deleted file mode 100644 index 16efed5313c4e5..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/misc/array_segment.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -// Structs come from from System.Net.Sockets tests -internal struct FakeArraySegment -{ - public byte[] Array; - public int Offset; - public int Count; - - public ArraySegment ToActual() - { - ArraySegmentWrapper wrapper = default(ArraySegmentWrapper); - wrapper.Fake = this; - return wrapper.Actual; - } -} - -[StructLayout(LayoutKind.Explicit)] -internal struct ArraySegmentWrapper -{ - [FieldOffset(0)] public ArraySegment Actual; - [FieldOffset(0)] public FakeArraySegment Fake; -} - -public class Test_ExplicitLayoutWithArraySegment -{ - private void Run() - { - var fakeArraySegment = new FakeArraySegment() { Array = new byte[10], Offset = 0, Count = 10 }; - ArraySegment internalBuffer = fakeArraySegment.ToActual(); - } - - public static int Main() - { - try - { - var testInstance = new Test_ExplicitLayoutWithArraySegment(); - testInstance.Run(); - } - catch (TypeLoadException e) - { - Console.WriteLine("FAIL: Caught TypeLoadException: " + e.Message); - return 101; - } - catch (Exception e) - { - Console.WriteLine("FAIL: Caught unexpected exception: " + e.Message); - return 101; - } - - return 100; - } -} diff --git a/src/tests/Loader/classloader/explicitlayout/misc/array_segment.csproj b/src/tests/Loader/classloader/explicitlayout/misc/array_segment.csproj deleted file mode 100644 index 451b532f2c9556..00000000000000 --- a/src/tests/Loader/classloader/explicitlayout/misc/array_segment.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - Exe - - - - - From 867a43493a4c4a78f45e2d7cadf61f9cf10f3ad1 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Thu, 2 Dec 2021 21:59:09 -0800 Subject: [PATCH 2/2] Revert "[mono] Fix StackTrace from a dim and Vtable offsets for static interface method (#60770)" This reverts commit 5789792167571c4121ef1d397e4678ba360c77b3. --- src/mono/mono/metadata/object.c | 2 - src/mono/mono/mini/mini-exceptions.c | 11 +- .../regressions/github60486.cs | 190 ------------------ .../regressions/github60486.csproj | 11 - 4 files changed, 2 insertions(+), 212 deletions(-) delete mode 100644 src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.cs delete mode 100644 src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.csproj diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 0c7240528adfa6..7def77c718f468 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -1518,8 +1518,6 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, gpointer* imt, GSList *extra_ * add_imt_builder_entry anyway. */ method = mono_class_get_method_by_index (mono_class_get_generic_class (iface)->container_class, method_slot_in_interface); - if (m_method_is_static (method)) - continue; if (mono_method_get_imt_slot (method) != slot_num) { vt_slot ++; continue; diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index 40f804499d0f24..fa139ec666821f 100644 --- a/src/mono/mono/mini/mini-exceptions.c +++ b/src/mono/mono/mini/mini-exceptions.c @@ -840,13 +840,12 @@ mono_get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_inf method = jinfo_get_method (ji); g_assert (method->is_inflated); - if (mono_method_get_context (method)->method_inst || mini_method_is_default_method (method)) { + if (mono_method_get_context (method)->method_inst) { MonoMethodRuntimeGenericContext *mrgctx = (MonoMethodRuntimeGenericContext *)generic_info; klass = mrgctx->class_vtable->klass; context.method_inst = mrgctx->method_inst; - if (!mini_method_is_default_method (method)) - g_assert (context.method_inst); + g_assert (context.method_inst); } else { MonoVTable *vtable = (MonoVTable *)generic_info; @@ -859,12 +858,6 @@ mono_get_generic_context_from_stack_frame (MonoJitInfo *ji, gpointer generic_inf else method_container_class = method->klass; - if (mini_method_is_default_method (method)) { - if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass)) - context.class_inst = mini_class_get_context (klass)->class_inst; - return context; - } - /* class might refer to a subclass of method's class */ while (!(klass == method->klass || (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->container_class == method_container_class))) { klass = m_class_get_parent (klass); diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.cs b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.cs deleted file mode 100644 index f32ff4725d5592..00000000000000 --- a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.cs +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Runtime.CompilerServices; - -public interface IPublisher -{ - event Action OnPublish; -} - -public interface TestItf1 -{ - [MethodImpl(MethodImplOptions.NoInlining)] - void TestMethod1(IPublisher publisher, StackFrame[] expectedFrames) - { - StackFrame.Validate(Environment.StackTrace, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - void TestMethod2(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod3(this, publisher, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - protected static void TestMethod3(TestItf1 subscriber, IPublisher publisher, StackFrame[] expectedFrames) - { - StackFrame.Validate(Environment.StackTrace, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - void TestMethod4(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod3(this, publisher, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - void TestMethod5(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod3(this, publisher, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - void TestMethod10(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod3(this, publisher, expectedFrames); - } - - void TestMethod11(IPublisher publisher, StackFrame[] expectedFrames); -} - -public interface TestItf2 : TestItf1 -{ - [MethodImpl(MethodImplOptions.NoInlining)] - void TestItf1.TestMethod5(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod3(this, publisher, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - void TestItf1.TestMethod10(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod3(this, publisher, expectedFrames); - } -} - -public interface TestItf3 : TestItf1 -{ - [MethodImpl(MethodImplOptions.NoInlining)] - void TestMethod6(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod3(this, publisher, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - void TestMethod7(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod8(this, publisher, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - protected static void TestMethod8(TestItf1 subscriber, IPublisher publisher, StackFrame[] expectedFrames) - { - StackFrame.Validate(Environment.StackTrace, expectedFrames); - } - - void TestMethod9(IPublisher publisher, StackFrame[] expectedFrames); -} - -public interface TestItf4 : TestItf3 -{ - [MethodImpl(MethodImplOptions.NoInlining)] - void TestItf3.TestMethod9(IPublisher publisher, StackFrame[] expectedFrames) - { - TestMethod8(this, publisher, expectedFrames); - } -} - -public class ProgramBase : TestItf4 -{ - [MethodImpl(MethodImplOptions.NoInlining)] - public void TestMethod10(IPublisher publisher, StackFrame[] expectedFrames) - { - TestItf1.TestMethod3(this, publisher, expectedFrames); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public void TestMethod11(IPublisher publisher, StackFrame[] expectedFrames) - { - TestItf1.TestMethod3(this, publisher, expectedFrames); - } -} - -public class Program : ProgramBase, TestItf2 -{ - static int Main(string[] args) - { - new Program().Start(); - return 100; - } - - public void Start() - { - var t1 = this as TestItf1; - t1.TestMethod1(null, new[] { new StackFrame("TestItf1`1", "TestMethod1") }); - t1.TestMethod2(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("TestItf1`1", "TestMethod2") }); - t1.TestMethod4(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("Program", "TestMethod4") }); - t1.TestMethod5(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame(new[] { "TestItf2`1", "TestItf1" }, "TestMethod5") }); - - var t3 = this as TestItf3; - t3.TestMethod6(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("TestItf3`1", "TestMethod6") }); - t3.TestMethod7(null, new[] { new StackFrame("TestItf3`1", "TestMethod8"), new StackFrame("TestItf3`1", "TestMethod7") }); - t3.TestMethod9(null, new[] { new StackFrame("TestItf3`1", "TestMethod8"), new StackFrame(new[] { "TestItf4`1", "TestItf3" }, "TestMethod9") }); - - t1.TestMethod10(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("ProgramBase`1", "TestMethod10") }); - t1.TestMethod11(null, new[] { new StackFrame("TestItf1`1", "TestMethod3"), new StackFrame("ProgramBase`1", "TestMethod11") }); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - public void TestMethod4(IPublisher publisher, StackFrame[] expectedFrames) - { - TestItf1.TestMethod3(this, publisher, expectedFrames); - } -} - -public class InputData -{ - public int i; -} - -public class StackFrame -{ - public string [] ClassName { get; set; } - public string MethodName { get; set; } = string.Empty; - - public StackFrame(string [] className, string methodName) - { - ClassName = className; - MethodName = methodName; - } - - public StackFrame(string className, string methodName) - { - ClassName = new string[] { className }; - MethodName = methodName; - } - - public static void Validate(string testStack, StackFrame[] expectedFrames) - { - int index = 1; - - string[] lines = testStack.Split( - new string[] { Environment.NewLine }, - StringSplitOptions.None - ); - - //Console.WriteLine(testStack); - - foreach (var frame in expectedFrames) - { - var line = lines[index++].Trim(); - - - if (!line.StartsWith($"at {frame.ClassName[0]}") || !line.Contains($".{frame.MethodName}") || (frame.ClassName.Length > 1 && !line.Contains($".{frame.ClassName[1]}"))) - { - Console.WriteLine($"Expected {frame.ClassName}.{frame.MethodName} but got {line}"); - Console.WriteLine(testStack); - Environment.Exit(1); - } - } - } -} \ No newline at end of file diff --git a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.csproj b/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.csproj deleted file mode 100644 index aab61d4e4497b8..00000000000000 --- a/src/tests/Loader/classloader/DefaultInterfaceMethods/regressions/github60486.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - true - Exe - BuildAndRun - 0 - - - - -