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

Crash at runtime likely related to protected accessibility of a method declared in an interface. #13466

Closed
AlekseyTs opened this issue Mar 14, 2019 · 6 comments

Comments

@AlekseyTs
Copy link

@AlekseyTs AlekseyTs commented Mar 14, 2019

The Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.DefaultInterfaceImplementationTests.ProtectedAccessibility_01 (in https://github.com/dotnet/roslyn/blob/features/DefaultInterfaceImplementation/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs) unit-test causes a crash at runtime:

=================================================================
	Native Crash Reporting
=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================
/proc/self/maps:
00400000-0087a000 r-xp 00000000 08:21 21108281                           /usr/bin/mono-sgen
00a7a000-00a81000 r--p 0047a000 08:21 21108281                           /usr/bin/mono-sgen
00a81000-00a86000 rw-p 00481000 08:21 21108281                           /usr/bin/mono-sgen
00a86000-00a9e000 rw-p 00000000 00:00 0 
011f1000-05ff0000 rw-p 00000000 00:00 0                                  [heap]
40059000-40109000 rwxp 00000000 00:00 0 
40173000-40399000 rwxp 00000000 00:00 0 
403a3000-40703000 rwxp 00000000 00:00 0 
40711000-40941000 rwxp 00000000 00:00 0 
40943000-40a16000 rwxp 00000000 00:00 0 
40cd8000-40df8000 rwxp 00000000 00:00 0 
40e05000-40e15000 rwxp 00000000 00:00 0 
40e30000-40f00000 rwxp 00000000 00:00 0 
410ca000-413ed000 rwxp 00000000 00:00 0 
41ba1000-41c71000 rwxp 00000000 00:00 0 
41f78000-42038000 rwxp 00000000 00:00 0 
7f4d5167c000-7f4d516fc000 rw-p 00000000 00:00 0 
7f4d51700000-7f4d51800000 rw-p 00000000 00:00 0 
7f4d5186c000-7f4d518ec000 rw-p 00000000 00:00 0 
7f4d518f0000-7f4d51970000 rw-p 00000000 00:00 0 
7f4d51974000-7f4d519f4000 rw-p 00000000 00:00 0 
7f4d519f8000-7f4d51a78000 rw-p 00000000 00:00 0 
7f4d51a7c000-7f4d51afc000 rw-p 00000000 00:00 0 
7f4d51b00000-7f4d51c00000 rw-p 00000000 00:00 0 
7f4d51c74000-7f4d51cf4000 rw-p 00000000 00:00 0 

=================================================================
	Native stacktrace:
=================================================================
	0x523376 - mono : (null)
	0x5236c1 - mono : (null)
	0x4ad2e1 - mono : (null)
	0x7f4dd0dac390 - /lib/x86_64-linux-gnu/libpthread.so.0 : (null)
	0x7f4dd0165428 - /lib/x86_64-linux-gnu/libc.so.6 : gsignal
	0x7f4dd016702a - /lib/x86_64-linux-gnu/libc.so.6 : abort
	0x72cb64 - mono : (null)
	0x712a51 - mono : (null)
	0x72ca4b - mono : (null)
	0x72d00d - mono : monoeg_assertion_message
	0x5a9479 - mono : (null)
	0x5fb250 - mono : (null)
	0x45e888 - mono : (null)
	0x46457c - mono : (null)
	0x45f69b - mono : (null)
	0x527fb3 - mono : (null)
	0x529f24 - mono : (null)
	0x42bb2f - mono : (null)
	0x42d779 - mono : (null)
	0x631a30 - mono : (null)
	0x63faf1 - mono : (null)
	0x5d5393 - mono : (null)
	0x41ba174c - Unknown

=================================================================
	Telemetry Dumper:
=================================================================
Pkilling 0x7f4dadc03700 from 0x7f4dd15dd780
Pkilling 0x7f4da57b3700 from 0x7f4dd15dd780
Pkilling 0x7f4dad12f700 from 0x7f4dd15dd780
Pkilling 0x7f4dccefc700 from 0x7f4dd15dd780
Pkilling 0x7f4dad54f700 from 0x7f4dd15dd780
Pkilling 0x7f4dad96f700 from 0x7f4dd15dd780
Pkilling 0x7f4d87651700 from 0x7f4dd15dd780
Pkilling 0x7f4d8724f700 from 0x7f4dd15dd780
Pkilling 0x7f4da4215700 from 0x7f4dd15dd780
Pkilling 0x7f4d86e4d700 from 0x7f4dd15dd780
Pkilling 0x7f4d86a4b700 from 0x7f4dd15dd780
Pkilling 0x7f4d86649700 from 0x7f4dd15dd780
Pkilling 0x7f4dc5fcc700 from 0x7f4dd15dd780
Pkilling 0x7f4dc5bca700 from 0x7f4dd15dd780
Pkilling 0x7f4dadf1b700 from 0x7f4dd15dd780
Pkilling 0x7f4d87450700 from 0x7f4dd15dd780
Pkilling 0x7f4d8704e700 from 0x7f4dd15dd780
Pkilling 0x7f4d86c4c700 from 0x7f4dd15dd780
Pkilling 0x7f4d8684a700 from 0x7f4dd15dd780
Pkilling 0x7f4dae2b7700 from 0x7f4dd15dd780
Pkilling 0x7f4dc61cd700 from 0x7f4dd15dd780
Pkilling 0x7f4dc5dcb700 from 0x7f4dd15dd780
Entering thread summarizer pause from 0x7f4dd15dd780
Finished thread summarizer pause from 0x7f4dd15dd780.

Waiting for dumping threads to resume

=================================================================
	External Debugger Dump:
=================================================================
mono_gdb_render_native_backtraces not supported on this platform, unable to find gdb or lldb

=================================================================
	Basic Fault Adddress Reporting
=================================================================
Memory around native instruction pointer (0x7f4dd0165428):0x7f4dd0165418  48 63 f0 48 63 d7 b8 ea 00 00 00 48 63 f9 0f 05  Hc.Hc......Hc...
0x7f4dd0165428  48 3d 00 f0 ff ff 77 20 f3 c3 66 0f 1f 44 00 00  H=....w ..f..D..
0x7f4dd0165438  85 c9 7f df 89 ca f7 da 81 e1 ff ff ff 7f 0f 44  ...............D
0x7f4dd0165448  d6 89 d1 eb ce 0f 1f 00 48 8b 15 21 ea 38 00 f7  ........H..!.8..

=================================================================
	Managed Stacktrace:
=================================================================
	  at <unknown> <0xffffffff>
	  at System.Reflection.RuntimeMethodInfo:InternalInvoke <0x0007b>
	  at System.Reflection.RuntimeMethodInfo:Invoke <0x00142>
	  at System.Reflection.MethodBase:Invoke <0x00045>
	  at <>c__DisplayClass33_0:<Execute>b__0 <0x00152>
	  at Roslyn.Test.Utilities.Desktop.DesktopRuntimeEnvironment:Capture <0x00152>
	  at Roslyn.Test.Utilities.Desktop.RuntimeAssemblyManager:Execute <0x001c3>
	  at Roslyn.Test.Utilities.Desktop.RuntimeAssemblyManager:Execute <0x000d3>
	  at Roslyn.Test.Utilities.Desktop.RuntimeAssemblyManager:Execute <0x00337>
	  at Roslyn.Test.Utilities.Desktop.RuntimeAssemblyManager:Execute <0x00232>
	  at Roslyn.Test.Utilities.Desktop.RuntimeAssemblyManager:Execute <0x0009f>
	  at Roslyn.Test.Utilities.Desktop.DesktopRuntimeEnvironment:Execute <0x00197>
	  at Microsoft.CodeAnalysis.Test.Utilities.CompilationVerifier:Emit <0x0013b>
	  at Microsoft.CodeAnalysis.Test.Utilities.CommonTestBase:Emit <0x00123>
	  at Microsoft.CodeAnalysis.Test.Utilities.CommonTestBase:CompileAndVerifyCommon <0x0021b>
	  at Microsoft.CodeAnalysis.CSharp.Test.Utilities.CSharpTestBase:CompileAndVerify <0x000a7>
	  at Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols.DefaultInterfaceImplementationTests:ProtectedAccessibility_01 <0x0018f>
	  at System.Object:runtime_invoke_void__this__ <0x00085>
	  at <unknown> <0xffffffff>
	  at System.Reflection.RuntimeMethodInfo:InternalInvoke <0x0007b>
	  at System.Reflection.RuntimeMethodInfo:Invoke <0x00142>
	  at System.Reflection.MethodBase:Invoke <0x00045>
	  at Xunit.Sdk.TestInvoker`1:CallTestMethod <0x0004a>
	  at <<InvokeTestMethodAsync>b__1>d:MoveNext <0x003ea>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder:Start <0x000cb>
	  at <>c__DisplayClass48_1:<InvokeTestMethodAsync>b__1 <0x0015b>
	  at <AggregateAsync>d__4:MoveNext <0x000db>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder:Start <0x000cb>
	  at Xunit.Sdk.ExecutionTimer:AggregateAsync <0x0018a>
	  at <>c__DisplayClass48_1:<InvokeTestMethodAsync>b__0 <0x0015f>
	  at <RunAsync>d__9:MoveNext <0x0008d>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder:Start <0x000c3>
	  at Xunit.Sdk.ExceptionAggregator:RunAsync <0x0017a>
	  at <InvokeTestMethodAsync>d__48:MoveNext <0x0035b>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000d3>
	  at Xunit.Sdk.TestInvoker`1:InvokeTestMethodAsync <0x0019b>
	  at Xunit.Sdk.XunitTestInvoker:InvokeTestMethodAsync <0x000ff>
	  at <<RunAsync>b__47_0>d:MoveNext <0x00756>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000db>
	  at Xunit.Sdk.TestInvoker`1:<RunAsync>b__47_0 <0x0015f>
	  at <RunAsync>d__10`1:MoveNext <0x00094>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000c3>
	  at Xunit.Sdk.ExceptionAggregator:RunAsync <0x00192>
	  at Xunit.Sdk.TestInvoker`1:RunAsync <0x000ef>
	  at Xunit.Sdk.XunitTestRunner:InvokeTestMethodAsync <0x000db>
	  at <InvokeTestAsync>d__4:MoveNext <0x001dd>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000d3>
	  at Xunit.Sdk.XunitTestRunner:InvokeTestAsync <0x0017a>
	  at <>c__DisplayClass43_0:<RunAsync>b__0 <0x00034>
	  at <RunAsync>d__10`1:MoveNext <0x0009c>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000cb>
	  at Xunit.Sdk.ExceptionAggregator:RunAsync <0x001cb>
	  at <RunAsync>d__43:MoveNext <0x0051f>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000db>
	  at Xunit.Sdk.TestRunner`1:RunAsync <0x00183>
	  at Xunit.Sdk.XunitTestCaseRunner:RunTestAsync <0x000d3>
	  at <RunAsync>d__19:MoveNext <0x0039a>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000d3>
	  at Xunit.Sdk.TestCaseRunner`1:RunAsync <0x00193>
	  at Xunit.Sdk.XunitTestCase:RunAsync <0x000bf>
	  at Xunit.Sdk.XunitTestMethodRunner:RunTestCaseAsync <0x0009e>
	  at <RunTestCasesAsync>d__32:MoveNext <0x001c8>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000db>
	  at Xunit.Sdk.TestMethodRunner`1:RunTestCasesAsync <0x00183>
	  at <RunAsync>d__31:MoveNext <0x001b8>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000cb>
	  at Xunit.Sdk.TestMethodRunner`1:RunAsync <0x00183>
	  at Xunit.Sdk.XunitTestClassRunner:RunTestMethodAsync <0x000eb>
	  at <RunTestMethodsAsync>d__38:MoveNext <0x00988>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000f3>
	  at Xunit.Sdk.TestClassRunner`1:RunTestMethodsAsync <0x00193>
	  at <RunAsync>d__37:MoveNext <0x003bd>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000d3>
	  at Xunit.Sdk.TestClassRunner`1:RunAsync <0x00193>
	  at Xunit.Sdk.XunitTestCollectionRunner:RunTestClassAsync <0x000fb>
	  at <RunTestClassesAsync>d__28:MoveNext <0x00448>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000db>
	  at Xunit.Sdk.TestCollectionRunner`1:RunTestClassesAsync <0x00183>
	  at <RunAsync>d__27:MoveNext <0x003ba>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000d3>
	  at Xunit.Sdk.TestCollectionRunner`1:RunAsync <0x00193>
	  at Xunit.Sdk.XunitTestAssemblyRunner:RunTestCollectionAsync <0x000c7>
	  at <RunTestCollectionsAsync>d__42:MoveNext <0x00239>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000d3>
	  at Xunit.Sdk.TestAssemblyRunner`1:RunTestCollectionsAsync <0x001e7>
	  at Xunit.Sdk.XunitTestAssemblyRunner:<>n__0 <0x00037>
	  at <RunTestCollectionsAsync>d__14:MoveNext <0x00293>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000cb>
	  at Xunit.Sdk.XunitTestAssemblyRunner:RunTestCollectionsAsync <0x001aa>
	  at <RunAsync>d__41:MoveNext <0x0062d>
	  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1:Start <0x000cb>
	  at Xunit.Sdk.TestAssemblyRunner`1:RunAsync <0x00197>
	  at <RunTestCases>d__8:MoveNext <0x00153>
	  at System.Runtime.CompilerServices.AsyncVoidMethodBuilder:Start <0x000bb>
	  at Xunit.Sdk.XunitTestFrameworkExecutor:RunTestCases <0x0022a>
	  at Xunit.Sdk.TestFrameworkExecutor`1:RunTests <0x000b1>
	  at Xunit.Sdk.TestFrameworkExecutor`1:RunTests <0x0032f>
	  at Xunit.Sdk.TestFrameworkExecutor`1:RunTests <0x00215>
	  at Xunit.Xunit2:RunTests <0x00064>
	  at Xunit.XunitFrontController:RunTests <0x00055>
	  at TestFrameworkExtensions:RunTests <0x00054>
	  at Xunit.ConsoleClient.ConsoleRunner:ExecuteAssembly <0x00ebb>
	  at Xunit.ConsoleClient.ConsoleRunner:RunProject <0x007ab>
	  at Xunit.ConsoleClient.ConsoleRunner:EntryPoint <0x007d7>
	  at Xunit.ConsoleClient.Program:Main <0x000e7>
	  at <Module>:runtime_invoke_int_object <0x00085>
=================================================================
@AlekseyTs

This comment has been minimized.

Copy link
Author

@AlekseyTs AlekseyTs commented Mar 14, 2019

@thaystg

This comment has been minimized.

Copy link
Contributor

@thaystg thaystg commented Mar 15, 2019

Source code to reproduce the Crash:

interface I1
{
   sealed void M1()
   {
       System.Console.WriteLine(“M1”);
   }
}


interface I2 : I1
{
   static void Test<T>(T x) where T : I2
   {
       x.M1();
   }
}

class A : I2
{
   static void Main()
   {
       I2.Test(new A());
   }
}
@AlekseyTs

This comment has been minimized.

Copy link
Author

@AlekseyTs AlekseyTs commented Mar 15, 2019

@thaystg The M1 doesn't have to be protected? In the unit-test it is protected:

interface I1
{
    sealed protected void M1()
    {
        System.Console.WriteLine(""M1"");
    }
}
thaystg added a commit to thaystg/mono that referenced this issue Mar 15, 2019
{
sealed void M1()
{
System.Console.WriteLine("M1");
}
}

interface I2 : I1
{
static void Test<T>(T x) where T : I2
{
x.M1();
}
}

class A : I2
{
static void Main()
{
I2.Test(new A());
}
}```

The interface method M1 is sealed so it's not virtual besides that it should be on vtable. Only static methods shouldn't be there.
Fixes mono#13466
@lambdageek

This comment has been minimized.

Copy link
Member

@lambdageek lambdageek commented Mar 15, 2019

@AlekseyTs question: is the IL for the example that @thaystg posted correct (IL included at the bottom of the message).

In particular the body of I2.Test<T> has a constrained.callvirt call to I1.M1. Is that really meant to be a virtual call?

Is something like this legal:

interface IBase {
    void Method ()  { Console.WriteLine ("In Base"); }
}

interface I1 : IBase {
   sealed void Method () { Console.WriteLine ("In I1"); }
}

class C : I1 {
  static void Test<T> (T x) where T : IBase
  {
      x.Method (); // virtual call?
   }
}

should this return "In Base" or "In I1"?

original IL ``` .assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. } .assembly '13466' { .custom instance void class [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::'.ctor'(int32) = (01 00 08 00 00 00 00 00 ) // ........

.custom instance void class [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::'.ctor'() = (
01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.

.custom instance void class [mscorlib]System.Diagnostics.DebuggableAttribute::'.ctor'(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = (01 00 07 01 00 00 00 00 ) // ........

.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module '13466.exe' // GUID = {A4E97AD7-126F-4034-838B-627DE47F9E63}

.class interface private auto ansi abstract I1
{

// method line 1
.method public hidebysig 
       instance default void M1 ()  cil managed 
{
    // Method begins at RVA 0x2050
// Code size 13 (0xd)
.maxstack 8
IL_0000:  nop 
IL_0001:  ldstr "M1"
IL_0006:  call void class [mscorlib]System.Console::WriteLine(string)
IL_000b:  nop 
IL_000c:  ret 
} // end of method I1::M1

} // end of class I1

.class interface private auto ansi abstract I2
implements I1 {

// method line 2
.method public static hidebysig 
       default void Test<(class I2) T> (!!T x)  cil managed 
{
    // Method begins at RVA 0x205e
// Code size 16 (0x10)
.maxstack 8
IL_0000:  nop 
IL_0001:  ldarga.s 0
IL_0003:  constrained. !!0
IL_0009:  call instance void class I1::M1()
IL_000e:  nop 
IL_000f:  ret 
} // end of method I2::Test

} // end of class I2

.class private auto ansi beforefieldinit A
extends [mscorlib]System.Object
implements I2, I1 {

// method line 3
.method private static hidebysig 
       default void Main ()  cil managed 
{
    // Method begins at RVA 0x206f
.entrypoint
// Code size 13 (0xd)
.maxstack 8
IL_0000:  nop 
IL_0001:  newobj instance void class A::'.ctor'()
IL_0006:  call void class I2::Test<class A> (!!0)
IL_000b:  nop 
IL_000c:  ret 
} // end of method A::Main

// method line 4
.method public hidebysig specialname rtspecialname 
       instance default void '.ctor' ()  cil managed 
{
    // Method begins at RVA 0x207d
// Code size 8 (0x8)
.maxstack 8
IL_0000:  ldarg.0 
IL_0001:  call instance void object::'.ctor'()
IL_0006:  nop 
IL_0007:  ret 
} // end of method A::.ctor

} // end of class A

</details>
@AlekseyTs

This comment has been minimized.

Copy link
Author

@AlekseyTs AlekseyTs commented Mar 15, 2019

is the IL for the example that @thaystg posted correct

According to ECMA-335: "The constrained. prefix is permitted only on a callvirt instruction."

Also, in section III.4.2 the spec says: "callvirt can be used to call both virtual and instance methods." My interpretation is that "instance methods" in this quote refers to non-virtual instance methods. Compiler often uses callvirt instruction to call non-virtual instance methods in order to take advantage of a null check performed by that instruction, as opposed to call instruction.

For example, for the following code:

class Test1
{
        void Test<T>(T x, object y) where T : System.Enum
        {
            System.Console.WriteLine(x.GetType());
            System.Console.WriteLine(y.GetType());
        }
}

C# compiler emits this IL (callvirt is used even though System.Object::GetType is not a virtual method):

.method private hidebysig instance void  Test<([mscorlib]System.Enum) T>(!!T x,
                                                                         object y) cil managed
{
  // Code size       33 (0x21)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarga.s   x
  IL_0003:  constrained. !!T
  IL_0009:  callvirt   instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
  IL_000e:  call       void [mscorlib]System.Console::WriteLine(object)
  IL_0013:  nop
  IL_0014:  ldarg.2
  IL_0015:  callvirt   instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
  IL_001a:  call       void [mscorlib]System.Console::WriteLine(object)
  IL_001f:  nop
  IL_0020:  ret
} // end of method Test1::Test

For the scenario in the unit-test, compiler emits this IL:

  // Code size       16 (0x10)
  .maxstack  1
  IL_0000:  nop
  IL_0001:  ldarga.s   V_0
  IL_0003:  constrained. ""T""
  IL_0009:  callvirt   ""void I1.M1()""
  IL_000e:  nop
  IL_000f:  ret

This looks correct to me, even though I1.M1 is not a virtual method (note the sealed modifier on the definition of the method).

Regarding the other scenario.

Since IBase.Method is not static or sealed, it is considered to be virtual and all calls to this method in C# are virtual, with exception of a base access, which has a special syntactic form.

The syntax to implement a method from base interface in a derived interface is different, an explicit interface implementation syntax should be used. Like this:

interface I1 : IBase {
   void IBase.Method () { Console.WriteLine ("In I1"); }
}

With this adjustment, the following code is supposed to call I1.IBase.Method, assuming the method is not re-implemented by a more derived type:

class C : I1 {
  static void Test<T> (T x) where T : IBase
  {
      x.Method (); // virtual call
   }
}
@lambdageek

This comment has been minimized.

Copy link
Member

@lambdageek lambdageek commented Mar 15, 2019

@AlekseyTs thanks for the detailed explanation.

@thaystg So for the original test case, in method-to-ir we should treat it like a callvirt of a non-virtual method and fix the codepath that leads to the assertion. We shouldn't treat sealed methods in DIMs like they're virtual.

thaystg added a commit to thaystg/mono that referenced this issue Mar 18, 2019
interface I1
{
   sealed void M1()
   {
       System.Console.WriteLine(“M1”);
   }
}

interface I2 : I1
{
   static void Test<T>(T x) where T : I2
   {
       x.M1();
   }
}

class A : I2
{
   static void Main()
   {
       I2.Test(new A());
   }
}
'''

When an interface implements a Sealed method, this method is not virtual, so it will not be available at vtable. But in the IL the call is a virtual call, but in this case we don't need to search at vtable.

Fixes mono#13466
thaystg added a commit that referenced this issue Mar 18, 2019
* '''
interface I1
{
   sealed void M1()
   {
       System.Console.WriteLine(“M1”);
   }
}

interface I2 : I1
{
   static void Test<T>(T x) where T : I2
   {
       x.M1();
   }
}

class A : I2
{
   static void Main()
   {
       I2.Test(new A());
   }
}
'''

When an interface implements a Sealed method, this method is not virtual, so it will not be available at vtable. But in the IL the call is a virtual call, but in this case we don't need to search at vtable.

Fixes #13466

* Change IL test.
alexanderkyte added a commit to alexanderkyte/mono that referenced this issue Mar 27, 2019
* '''
interface I1
{
   sealed void M1()
   {
       System.Console.WriteLine(“M1”);
   }
}

interface I2 : I1
{
   static void Test<T>(T x) where T : I2
   {
       x.M1();
   }
}

class A : I2
{
   static void Main()
   {
       I2.Test(new A());
   }
}
'''

When an interface implements a Sealed method, this method is not virtual, so it will not be available at vtable. But in the IL the call is a virtual call, but in this case we don't need to search at vtable.

Fixes mono#13466

* Change IL test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.