using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.UnreachableBlock { [SetupLinkerSubstitutionFile ("InstanceMethodSubstitutions.xml")] [SetupCSharpCompilerToUse ("csc")] [SetupCompileArgument ("/optimize+")] [SetupLinkerArgument ("--enable-opt", "ipconstprop")] public class InstanceMethodSubstitutions { [Kept] private InstanceMethodSubstitutions () { } public static void Main () { var instance = new InstanceMethodSubstitutions (); instance.TestSimpleCallsite (); instance.TestCallOnInstance (); instance.TestCallOnInstanceMulti (); instance.TestInstanceMethodWithoutSubstitution (); instance.TestPropagation (); instance.TestStaticPropagation (); instance.TestVirtualMethod (); } bool _isEnabledField; [Kept] [ExpectBodyModified] bool IsEnabled () { return _isEnabledField; } InstanceMethodSubstitutions GetInstance () { return null; } static bool PropFalse { get { return false; } } [Kept] [ExpectedInstructionSequence (new[] { "nop", "ldnull", "callvirt System.Boolean Mono.Linker.Tests.Cases.UnreachableBlock.InstanceMethodSubstitutions::IsEnabled()", "brfalse.s il_9", "ldarg.0", "call System.Void Mono.Linker.Tests.Cases.UnreachableBlock.InstanceMethodSubstitutions::CallOnInstance_Reached()", "ret", })] void TestCallOnInstance () { if (GetInstance ().IsEnabled ()) CallOnInstance_NeverReached (); else CallOnInstance_Reached (); } [Kept] [ExpectedInstructionSequence (new[] { "ldc.i4.0", "brfalse.s il_3", "ldc.i4.1", "ret" })] int TestCallOnInstanceMulti () { if (PropFalse && GetInstance ().IsEnabled ()) return 3; else return 1; } void CallOnInstance_NeverReached () { } [Kept] void CallOnInstance_Reached () { } [Kept] [ExpectBodyModified] void TestSimpleCallsite () { if (IsEnabled ()) SimpleCallsite_NeverReached (); else SimpleCallsite_Reached (); } void SimpleCallsite_NeverReached () { } [Kept] void SimpleCallsite_Reached () { } [Kept] [ExpectedInstructionSequence (new[] { "nop", "ldc.i4.1", "pop", "ldarg.0", "call System.Void Mono.Linker.Tests.Cases.UnreachableBlock.InstanceMethodSubstitutions::InstanceMethodWithoutSubstitution_Reached1()", "ret", })] void TestInstanceMethodWithoutSubstitution () { InstanceMethodSubstitutions ims = this; if (ims.InstanceMethodWithoutSubstitution ()) InstanceMethodWithoutSubstitution_Reached1 (); else InstanceMethodWithoutSubstitution_Reached2 (); } bool InstanceMethodWithoutSubstitution () { return true; } [Kept] void InstanceMethodWithoutSubstitution_Reached1 () { } void InstanceMethodWithoutSubstitution_Reached2 () { } [Kept] [ExpectedInstructionSequence (new[] { "nop", "ldc.i4.0", "brfalse.s il_4", "ldarg.0", "call System.Void Mono.Linker.Tests.Cases.UnreachableBlock.InstanceMethodSubstitutions::Propagation_Reached2()", "ret", })] void TestPropagation () { if (PropagateIsEnabled ()) Propagation_Reached1 (); else Propagation_Reached2 (); } bool PropagateIsEnabled () { return IsEnabled (); } void Propagation_Reached1 () { } [Kept] void Propagation_Reached2 () { } [Kept] [ExpectedInstructionSequence (new[] { "call System.Boolean Mono.Linker.Tests.Cases.UnreachableBlock.InstanceMethodSubstitutions::PropagateStaticIsEnabled()", "brfalse.s il_7", "ldarg.0", "call System.Void Mono.Linker.Tests.Cases.UnreachableBlock.InstanceMethodSubstitutions::StaticPropagation_Reached2()", "ret", })] void TestStaticPropagation () { if (PropagateStaticIsEnabled ()) StaticPropagation_Reached1 (); else StaticPropagation_Reached2 (); } [Kept] private static InstanceMethodSubstitutions _staticInstance; [Kept] static bool PropagateStaticIsEnabled () { return _staticInstance.IsEnabled (); } void StaticPropagation_Reached1 () { } [Kept] void StaticPropagation_Reached2 () { } [Kept] void TestVirtualMethod () { TestVirtualMethodBase instance = new TestVirtualMethodType (); // Virtual method return value inlining not supported if (instance.IsEnabled ()) VirtualMethod_Reached1 (); else VirtualMethod_Reached2 (); } [Kept] [KeptMember (".ctor()")] class TestVirtualMethodBase { [Kept] [ExpectBodyModified] public virtual bool IsEnabled () { return false; } } [Kept] [KeptMember (".ctor()")] [KeptBaseType (typeof (TestVirtualMethodBase))] class TestVirtualMethodType : TestVirtualMethodBase { [Kept] [ExpectBodyModified] public override bool IsEnabled () { return false; } } [Kept] void VirtualMethod_Reached1 () { } [Kept] void VirtualMethod_Reached2 () { } } }