summaryrefslogtreecommitdiff
path: root/tests/src/Loader/classloader/TypeInitialization
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src/Loader/classloader/TypeInitialization')
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.cs81
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.cs309
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.il348
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.cs429
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.cs136
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.il346
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.il127
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.cs136
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.il346
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.il200
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/app.config27
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/project.json35
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.cs192
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.il463
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.cs163
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.il448
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.cs177
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.il451
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.cs180
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.il454
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/app.config27
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CircularCctors/project.json35
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.il346
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.ilproj38
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.cs180
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CoreCLR/app.config27
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/CoreCLR/project.json35
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.cs127
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.cs155
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.cs126
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.cs154
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.cs126
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.cs154
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/app.config27
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/Inlining/project.json35
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.cs70
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.cs64
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.cs65
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.csproj39
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/app.config27
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/project.json35
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/backpatching/app.config27
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/backpatching/project.json35
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/backpatching/test1.cs81
-rw-r--r--tests/src/Loader/classloader/TypeInitialization/backpatching/test1.csproj39
72 files changed, 8166 insertions, 0 deletions
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.cs
new file mode 100644
index 0000000000..29cd9ea2c1
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.cs
@@ -0,0 +1,81 @@
+// 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.
+
+/*
+Open and write to a file inside static class constructor of a class/struct (eager and beforefieldinit cases).
+Access type's static field (which would trigger the .cctor)
+Expected: Should get no exceptions.
+
+*/
+
+using System;
+using System.IO;
+
+public class MyClass
+{
+ public static int counter;
+
+ static MyClass()
+ {
+ Console.WriteLine("Inside class cctor");
+
+ File.WriteAllText("file.txt", "inside MyClass.cctor");
+
+ counter++;
+ }
+}
+
+public struct MyStruct
+{
+
+ public static int counter;
+
+ static MyStruct()
+ {
+ Console.WriteLine("Inside struct cctor");
+
+ File.WriteAllText("file.txt", "inside MyClass.cctor");
+
+ counter++;
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+
+ int ret;
+ try
+ {
+ File.WriteAllText("file.txt", "inside Main");
+
+
+ if (MyClass.counter == 1 && MyStruct.counter == 1)
+ {
+ Console.WriteLine("PASS");
+ ret = 100;
+ }
+ else
+ {
+ Console.WriteLine("Fail: One of the .cctors wasn't called");
+ ret = 101;
+ }
+
+ if (File.Exists("file.txt"))
+ {
+ File.Delete("file.txt");
+ }
+
+ return ret;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("FAIL: Caught unexpected exception: " + e);
+ return 102;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.csproj
new file mode 100644
index 0000000000..7b73adf9c7
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorOpenFile.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorOpenFile</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorOpenFile.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.cs
new file mode 100644
index 0000000000..4a220d410b
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.cs
@@ -0,0 +1,309 @@
+// 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.
+
+/*
+
+A .cctor has only one chance to run in any appdomain.
+If it fails, the 2nd time we try to access a static field we check if .cctor has been run. And it has, but failed so we fail again.
+
+Test throws an exception inside .cctor.
+Try to access a static method twice for inlined and not inlined methods.
+Expected: Should return the same exception.
+
+*/
+
+
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+public class Foo
+{
+ public static void Meth_In()
+ {
+ // NotInlined.NotInlinedMeth is not inlined
+ NotInlined.NotInlinedMeth();
+ }
+
+ public static void Meth_NotIn()
+ {
+ // Inlined.InlinedMeth is inlined
+ Inlined.InlinedMeth();
+ }
+
+ public static void ValMeth_In()
+ {
+ // NotInlinedVal.NotInlinedValMeth is not inlined
+ NotInlinedVal.NotInlinedValMeth();
+ }
+
+ public static void ValMeth_NotIn()
+ {
+ // InlinedVal.InlinedValMeth is inlined
+ InlinedVal.InlinedValMeth();
+ }
+}
+
+public class NotInlined
+{
+
+ static NotInlined()
+ {
+ Console.WriteLine("Inside NotInlined::.cctor");
+ throw new Exception();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedMeth()
+ {
+ }
+}
+
+
+public class Inlined
+{
+
+ static Inlined()
+ {
+ Console.WriteLine("Inside Inlined::.cctor");
+ throw new Exception();
+ }
+
+ public static void InlinedMeth()
+ {
+ }
+}
+
+
+public struct NotInlinedVal
+{
+
+ static NotInlinedVal()
+ {
+ Console.WriteLine("Inside NotInlinedVal::.cctor");
+ throw new Exception();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedValMeth()
+ {
+ }
+}
+
+
+public class InlinedVal
+{
+
+ static InlinedVal()
+ {
+ Console.WriteLine("Inside InlinedVal::.cctor");
+ throw new Exception();
+ }
+
+ public static void InlinedValMeth()
+ {
+ }
+}
+
+public class Test
+{
+
+
+ public static bool RunTest(int i)
+ {
+ bool result = true;
+
+ switch (i)
+ {
+ case 1:
+ {
+ try
+ {
+ Console.WriteLine("Accessing class's inlined static method");
+ Foo.Meth_In();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ Foo.Meth_In();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception\n");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ case 2:
+ {
+ try
+ {
+ Console.WriteLine("Accessing struct's inlined static method");
+ Foo.ValMeth_In();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ Foo.ValMeth_In();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ case 3:
+ {
+ try
+ {
+ Console.WriteLine("Accessing class's not inlined static method");
+
+ Foo.Meth_NotIn();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ Foo.Meth_NotIn();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ case 4:
+ {
+ try
+ {
+ Console.WriteLine("Accessing struct's not inlined static method");
+ Foo.ValMeth_NotIn();
+
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ Foo.ValMeth_NotIn();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception\n");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+
+ default :
+ return false;
+ }
+ }
+
+
+ public static int Main()
+ {
+ bool pass = true;
+
+ // run tests
+ if (!RunTest(1))
+ pass = false;
+
+ if (!RunTest(2))
+ pass = false;
+
+ if (!RunTest(3))
+ pass = false;
+
+ if (!RunTest(4))
+ pass = false;
+
+ if (pass)
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.csproj
new file mode 100644
index 0000000000..503d666b9b
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowInlinedStatic.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorThrowInlinedStatic</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorThrowInlinedStatic.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.il
new file mode 100644
index 0000000000..dc73aea0e7
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.il
@@ -0,0 +1,348 @@
+// 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.
+
+.assembly extern System.Console { }
+// A .cctor has only one chance to run in any appdomain.
+// If it fails, the 2nd time we try to access a static field we check if .cctor has been run.
+// And it has, but failed so we fail again.
+
+// Test throws an exception inside .cctor.
+// Try to access a static method using LDFTN op code
+// Expected: Should return the same exception.
+
+
+
+// Metadata version: v2.0.50117
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly CctorThrowLDFTNStaticMethod
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module CctorThrowLDFTNStaticMethod.exe
+// MVID: {DFA6FFCF-599E-4DF2-8538-B842C6A0AD10}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public auto ansi A
+ extends [mscorlib]System.Object
+{
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 18 (0x12)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "Inside A.cctor"
+ IL_0006: call void [System.Console]System.Console::WriteLine(string)
+ IL_000b: nop
+ IL_000c: newobj instance void [mscorlib]System.Exception::.ctor()
+ IL_0011: throw
+ } // end of method A::.cctor
+
+ .method public hidebysig static void StaticMethod() cil managed
+ {
+ // Code size 2 (0x2)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ret
+ } // end of method A::StaticMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+.class public sequential ansi sealed B
+ extends [mscorlib]System.ValueType
+{
+ .pack 0
+ .size 1
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 18 (0x12)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "Inside B.cctor"
+ IL_0006: call void [System.Console]System.Console::WriteLine(string)
+ IL_000b: nop
+ IL_000c: newobj instance void [mscorlib]System.Exception::.ctor()
+ IL_0011: throw
+ } // end of method B::.cctor
+
+ .method public hidebysig static void StaticMethod() cil managed
+ {
+ // Code size 2 (0x2)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ret
+ } // end of method B::StaticMethod
+
+} // end of class B
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 279 (0x117)
+ .maxstack 2
+ .locals init (bool V_0,
+ class [mscorlib]System.Exception V_1,
+ int32 V_2,
+ bool V_3)
+ IL_0000: nop
+ IL_0001: ldc.i4.1
+ IL_0002: stloc.0
+ .try
+ {
+ IL_0003: nop
+ IL_0004: ldstr "LDFTN static method of a class"
+ IL_0009: call void [System.Console]System.Console::WriteLine(string)
+ IL_000e: nop
+
+
+ // LDFTN static method of a class
+ ldftn void A::StaticMethod()
+ calli void ()
+
+
+ IL_000f: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_0014: call void [System.Console]System.Console::WriteLine(string)
+ IL_0019: nop
+ IL_001a: ldc.i4.0
+ IL_001b: stloc.0
+ IL_001c: nop
+ IL_001d: leave.s IL_0047
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_001f: pop
+ IL_0020: nop
+ IL_0021: ldstr "Caught expected exception 1st time"
+ IL_0026: call void [System.Console]System.Console::WriteLine(string)
+ IL_002b: nop
+ IL_002c: nop
+ IL_002d: leave.s IL_0047
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_002f: stloc.1
+ IL_0030: nop
+ IL_0031: ldstr "Caught unexpected exception 1st time: "
+ IL_0036: ldloc.1
+ IL_0037: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_003c: call void [System.Console]System.Console::WriteLine(string)
+ IL_0041: nop
+ IL_0042: ldc.i4.0
+ IL_0043: stloc.0
+ IL_0044: nop
+ IL_0045: leave.s IL_0047
+
+ } // end handler
+ IL_0047: nop
+ .try
+ {
+ IL_0048: nop
+
+ // LDFTN static method of a class
+ ldftn void A::StaticMethod()
+ calli void ()
+
+ IL_0049: ldstr "Did not catch expected TypeInitializationException"
+ + " exception\n"
+ IL_004e: call void [System.Console]System.Console::WriteLine(string)
+ IL_0053: nop
+ IL_0054: ldc.i4.0
+ IL_0055: stloc.0
+ IL_0056: nop
+ IL_0057: leave.s IL_0081
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_0059: pop
+ IL_005a: nop
+ IL_005b: ldstr "Caught expected exception 2nd time\n"
+ IL_0060: call void [System.Console]System.Console::WriteLine(string)
+ IL_0065: nop
+ IL_0066: nop
+ IL_0067: leave.s IL_0081
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_0069: stloc.1
+ IL_006a: nop
+ IL_006b: ldstr "Caught unexpected exception 2nd time: "
+ IL_0070: ldloc.1
+ IL_0071: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0076: call void [System.Console]System.Console::WriteLine(string)
+ IL_007b: nop
+ IL_007c: ldc.i4.0
+ IL_007d: stloc.0
+ IL_007e: nop
+ IL_007f: leave.s IL_0081
+
+ } // end handler
+ IL_0081: nop
+ .try
+ {
+ IL_0082: nop
+ IL_0083: ldstr "LDFTN static method of a struct"
+ IL_0088: call void [System.Console]System.Console::WriteLine(string)
+ IL_008d: nop
+
+ // LDFTN static method of a struct
+ ldftn void B::StaticMethod()
+ calli void ()
+
+ IL_008e: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_0093: call void [System.Console]System.Console::WriteLine(string)
+ IL_0098: nop
+ IL_0099: ldc.i4.0
+ IL_009a: stloc.0
+ IL_009b: nop
+ IL_009c: leave.s IL_00c6
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_009e: pop
+ IL_009f: nop
+ IL_00a0: ldstr "Caught expected exception 1st time"
+ IL_00a5: call void [System.Console]System.Console::WriteLine(string)
+ IL_00aa: nop
+ IL_00ab: nop
+ IL_00ac: leave.s IL_00c6
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_00ae: stloc.1
+ IL_00af: nop
+ IL_00b0: ldstr "Caught unexpected exception 1st time: "
+ IL_00b5: ldloc.1
+ IL_00b6: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_00bb: call void [System.Console]System.Console::WriteLine(string)
+ IL_00c0: nop
+ IL_00c1: ldc.i4.0
+ IL_00c2: stloc.0
+ IL_00c3: nop
+ IL_00c4: leave.s IL_00c6
+
+ } // end handler
+ IL_00c6: nop
+ .try
+ {
+ IL_00c7: nop
+
+ // LDFTN static method of a struct
+ ldftn void B::StaticMethod()
+ calli void ()
+
+ IL_00c8: ldstr "Did not catch expected TypeInitializationException"
+ + " exception\n"
+ IL_00cd: call void [System.Console]System.Console::WriteLine(string)
+ IL_00d2: nop
+ IL_00d3: ldc.i4.0
+ IL_00d4: stloc.0
+ IL_00d5: nop
+ IL_00d6: leave.s IL_0100
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_00d8: pop
+ IL_00d9: nop
+ IL_00da: ldstr "Caught expected exception 2nd time\n"
+ IL_00df: call void [System.Console]System.Console::WriteLine(string)
+ IL_00e4: nop
+ IL_00e5: nop
+ IL_00e6: leave.s IL_0100
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_00e8: stloc.1
+ IL_00e9: nop
+ IL_00ea: ldstr "Caught unexpected exception 2nd time: "
+ IL_00ef: ldloc.1
+ IL_00f0: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_00f5: call void [System.Console]System.Console::WriteLine(string)
+ IL_00fa: nop
+ IL_00fb: ldc.i4.0
+ IL_00fc: stloc.0
+ IL_00fd: nop
+ IL_00fe: leave.s IL_0100
+
+ } // end handler
+ IL_0100: nop
+ IL_0101: ldloc.0
+ IL_0102: ldc.i4.0
+ IL_0103: ceq
+ IL_0105: stloc.3
+ IL_0106: ldloc.3
+ IL_0107: brtrue.s IL_010f
+
+ IL_0109: nop
+ IL_010a: ldc.i4.s 100
+ IL_010c: stloc.2
+ IL_010d: br.s IL_0115
+
+ IL_010f: nop
+ IL_0110: ldc.i4.s 101
+ IL_0112: stloc.2
+ IL_0113: br.s IL_0115
+
+ IL_0115: ldloc.2
+ IL_0116: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file CctorThrowLDFTNStaticMethod.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.ilproj
new file mode 100644
index 0000000000..280674411f
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowLDFTNStaticMethod.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorThrowLDFTNStaticMethod</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorThrowLDFTNStaticMethod.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.cs
new file mode 100644
index 0000000000..f7e38a6770
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.cs
@@ -0,0 +1,429 @@
+// 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.
+
+/*
+
+A .cctor has only one chance to run in any appdomain.
+If it fails, the 2nd time we try to access a static field we check if .cctor has been run. And it has, but failed so we fail again.
+
+Test throws an exception inside .cctor.
+Try to access a static method twice.
+Expected: Should return the same exception.
+
+*/
+
+using System;
+
+// TEST1
+// static method access
+public class A
+{
+ static A()
+ {
+ Console.WriteLine("In A.cctor");
+
+ throw new Exception();
+ }
+
+ public static void methA()
+ {}
+}
+
+// TEST2
+// static method access
+public struct B
+{
+ static B()
+ {
+ Console.WriteLine("In B.cctor");
+
+ throw new Exception();
+ }
+
+ public static void methB()
+ {}
+}
+
+// TEST3
+// instance constructor trigger
+public class C
+{
+ static C()
+ {
+ Console.WriteLine("In C.cctor");
+
+ throw new Exception();
+ }
+}
+
+// TEST4
+// instance constructor trigger
+public struct D
+{
+ static D()
+ {
+ Console.WriteLine("In D.cctor");
+
+ throw new Exception();
+ }
+
+ public D(int i){}
+}
+
+/*
+// this will fail due to current postponed bug so I've disabled it for now
+// TEST5
+// instance method trigger (for this null pointer)
+public class E
+{
+ static E()
+ {
+ Console.WriteLine("In E.cctor");
+
+ throw new Exception();
+ }
+
+ public void methE()
+ {}
+}
+*/
+
+// TEST6
+// instance method trigger (for zero initialized valuetype)
+public struct F
+{
+ static F()
+ {
+ Console.WriteLine("In F.cctor");
+
+ throw new Exception();
+ }
+
+ public void methF()
+ {}
+}
+
+public interface IG
+{
+ void methG();
+}
+
+// TEST7
+// virtual instance method trigger (for zero initialized valuetype)
+public struct G : IG
+{
+ static G()
+ {
+ Console.WriteLine("In G.cctor");
+
+ throw new Exception();
+ }
+
+ public void methG()
+ {}
+}
+
+
+
+public class Test
+{
+ public static bool RunTest(string s)
+ {
+ bool result = true;
+
+ switch (s)
+ {
+ case "A":
+ {
+ try
+ {
+ Console.WriteLine("Accessing class's static method");
+ A.methA();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ A.methA();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception\n");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ case "B":
+ {
+ try
+ {
+ Console.WriteLine("Accessing struct's static method");
+ B.methB();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ B.methB();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ case "C":
+ {
+ try
+ {
+ Console.WriteLine("Instantiating class");
+
+ C c = new C();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ C c = new C();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ case "D":
+ {
+ try
+ {
+ Console.WriteLine("Instantiating struct");
+ D d = new D(6);
+
+ // to get rid of compiler warning that var d is never used
+ string str = d.ToString();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ D d = new D(6);
+
+ // to get rid of compiler warning that var d is never used
+ string str = d.ToString();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception\n");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ case "F":
+ {
+ try
+ {
+ Console.WriteLine("Accessing struct's instance method (zero initialized struct)");
+ F f = new F();
+
+ f.methF();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ F f = new F();
+
+ f.methF();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ case "G":
+ {
+ try
+ {
+ Console.WriteLine("Accessing struct's virtual instance method (zero initialized struct)");
+ IG g = new G();
+
+ g.methG();
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+ try
+ {
+ IG g = new G();
+
+ g.methG();
+
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ return result;
+ }
+ default :
+ return false;
+ }
+ }
+
+
+ public static int Main()
+ {
+ bool pass = true;
+
+
+ Console.WriteLine("\n============================================================");
+ Console.WriteLine("NOTE: This test will fail with NGEN");
+ Console.WriteLine("We do not guarantee to execute static .cctor for structs");
+ Console.WriteLine("unless the instance .ctor is explicitly called\n");
+ Console.WriteLine("============================================================");
+
+
+ // run tests
+ if (!RunTest(typeof(A).ToString()))
+ pass = false;
+
+ if (!RunTest(typeof(B).ToString()))
+ pass = false;
+
+ if (!RunTest(typeof(C).ToString()))
+ pass = false;
+
+ if (!RunTest(typeof(D).ToString()))
+ pass = false;
+
+ if (!RunTest(typeof(F).ToString()))
+ pass = false;
+
+ if (!RunTest(typeof(G).ToString()))
+ pass = false;
+
+ if (pass)
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.csproj
new file mode 100644
index 0000000000..dd875e20b8
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowMethodAccess.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorThrowMethodAccess</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorThrowMethodAccess.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.cs
new file mode 100644
index 0000000000..859318e598
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.cs
@@ -0,0 +1,136 @@
+// 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.
+
+/*
+
+A .cctor has only one chance to run in any appdomain.
+If it fails, the 2nd time we try to access a static field we check if .cctor has been run. And it has, but failed so we fail again.
+
+Test throws an exception inside .cctor.
+Try to access a static field twice.
+Expected: Should return the same exception.
+
+*/
+
+using System;
+
+
+public class A
+{
+ public static int i;
+
+ static A()
+ {
+ Console.WriteLine("In A.cctor");
+
+ A.i = 5;
+
+ throw new Exception();
+ }
+}
+
+
+public struct B
+{
+ public static int i;
+
+ static B()
+ {
+ Console.WriteLine("In B.cctor");
+
+ B.i = 5;
+
+ throw new Exception();
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+ bool result = true;
+
+ try
+ {
+ Console.WriteLine("Accessing class's static field");
+ Console.WriteLine("A.i: " +A.i);
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+
+ try
+ {
+ Console.WriteLine("A.i: " +A.i);
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+
+ Console.WriteLine("Accessing struct's static field");
+ try
+ {
+ Console.WriteLine("B.i: " +B.i);
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+
+ try
+ {
+ Console.WriteLine("B.i: " +B.i);
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ if (result)
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.csproj
new file mode 100644
index 0000000000..e38b2384f1
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticField.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorThrowStaticField</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorThrowStaticField.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.il
new file mode 100644
index 0000000000..255282576c
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.il
@@ -0,0 +1,346 @@
+// 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.
+
+.assembly extern System.Console { }
+
+// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+
+
+// Metadata version: v2.0.50103
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly CctorThrowStaticFieldBFI
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module CctorThrowStaticFieldBFI.exe
+// MVID: {A7BE6B3C-FF8D-43DB-B091-60CBA24AD082}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public auto ansi beforefieldinit A
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 24 (0x18)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In A.cctor"
+ IL_0006: call void [System.Console]System.Console::WriteLine(string)
+ IL_000b: nop
+ IL_000c: ldc.i4.5
+ IL_000d: stsfld int32 A::i
+ IL_0012: newobj instance void [mscorlib]System.Exception::.ctor()
+ IL_0017: throw
+ } // end of method A::.cctor
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+.class public sequential ansi sealed B
+ extends [mscorlib]System.ValueType
+{
+ .pack 0
+ .size 1
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 24 (0x18)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In B.cctor"
+ IL_0006: call void [System.Console]System.Console::WriteLine(string)
+ IL_000b: nop
+ IL_000c: ldc.i4.5
+ IL_000d: stsfld int32 B::i
+ IL_0012: newobj instance void [mscorlib]System.Exception::.ctor()
+ IL_0017: throw
+ } // end of method B::.cctor
+
+} // end of class B
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 405 (0x195)
+ .maxstack 2
+ .locals init (bool V_0,
+ class [mscorlib]System.Exception V_1,
+ int32 V_2,
+ bool V_3)
+ IL_0000: nop
+ IL_0001: ldc.i4.1
+ IL_0002: stloc.0
+ .try
+ {
+ IL_0003: nop
+ IL_0004: ldstr "Accessing class's static field"
+ IL_0009: call void [System.Console]System.Console::WriteLine(string)
+ IL_000e: nop
+ IL_000f: ldstr "A.i: "
+ IL_0014: ldsfld int32 A::i
+ IL_0019: box [mscorlib]System.Int32
+ IL_001e: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0023: call void [System.Console]System.Console::WriteLine(string)
+ IL_0028: nop
+ IL_0029: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_002e: call void [System.Console]System.Console::WriteLine(string)
+ IL_0033: nop
+ IL_0034: ldc.i4.0
+ IL_0035: stloc.0
+ IL_0036: nop
+ IL_0037: leave.s IL_0061
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_0039: pop
+ IL_003a: nop
+ IL_003b: ldstr "Caught expected exception 1st time"
+ IL_0040: call void [System.Console]System.Console::WriteLine(string)
+ IL_0045: nop
+ IL_0046: nop
+ IL_0047: leave.s IL_0061
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_0049: stloc.1
+ IL_004a: nop
+ IL_004b: ldstr "Caught unexpected exception: "
+ IL_0050: ldloc.1
+ IL_0051: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0056: call void [System.Console]System.Console::WriteLine(string)
+ IL_005b: nop
+ IL_005c: ldc.i4.0
+ IL_005d: stloc.0
+ IL_005e: nop
+ IL_005f: leave.s IL_0061
+
+ } // end handler
+ IL_0061: nop
+ .try
+ {
+ IL_0062: nop
+ IL_0063: ldstr "A.i: "
+ IL_0068: ldsfld int32 A::i
+ IL_006d: box [mscorlib]System.Int32
+ IL_0072: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0077: call void [System.Console]System.Console::WriteLine(string)
+ IL_007c: nop
+ IL_007d: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_0082: call void [System.Console]System.Console::WriteLine(string)
+ IL_0087: nop
+ IL_0088: ldc.i4.0
+ IL_0089: stloc.0
+ IL_008a: nop
+ IL_008b: leave.s IL_00b5
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_008d: pop
+ IL_008e: nop
+ IL_008f: ldstr "Caught expected exception 2nd time\n"
+ IL_0094: call void [System.Console]System.Console::WriteLine(string)
+ IL_0099: nop
+ IL_009a: nop
+ IL_009b: leave.s IL_00b5
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_009d: stloc.1
+ IL_009e: nop
+ IL_009f: ldstr "Caught unexpected exception: "
+ IL_00a4: ldloc.1
+ IL_00a5: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_00aa: call void [System.Console]System.Console::WriteLine(string)
+ IL_00af: nop
+ IL_00b0: ldc.i4.0
+ IL_00b1: stloc.0
+ IL_00b2: nop
+ IL_00b3: leave.s IL_00b5
+
+ } // end handler
+ IL_00b5: nop
+ IL_00b6: ldstr "Accessing struct's static field"
+ IL_00bb: call void [System.Console]System.Console::WriteLine(string)
+ IL_00c0: nop
+ .try
+ {
+ IL_00c1: nop
+ IL_00c2: ldstr "B.i: "
+ IL_00c7: ldsfld int32 B::i
+ IL_00cc: box [mscorlib]System.Int32
+ IL_00d1: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_00d6: call void [System.Console]System.Console::WriteLine(string)
+ IL_00db: nop
+ IL_00dc: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_00e1: call void [System.Console]System.Console::WriteLine(string)
+ IL_00e6: nop
+ IL_00e7: ldc.i4.0
+ IL_00e8: stloc.0
+ IL_00e9: nop
+ IL_00ea: leave.s IL_0114
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_00ec: pop
+ IL_00ed: nop
+ IL_00ee: ldstr "Caught expected exception 1st time"
+ IL_00f3: call void [System.Console]System.Console::WriteLine(string)
+ IL_00f8: nop
+ IL_00f9: nop
+ IL_00fa: leave.s IL_0114
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_00fc: stloc.1
+ IL_00fd: nop
+ IL_00fe: ldstr "Caught unexpected exception: "
+ IL_0103: ldloc.1
+ IL_0104: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0109: call void [System.Console]System.Console::WriteLine(string)
+ IL_010e: nop
+ IL_010f: ldc.i4.0
+ IL_0110: stloc.0
+ IL_0111: nop
+ IL_0112: leave.s IL_0114
+
+ } // end handler
+ IL_0114: nop
+ .try
+ {
+ IL_0115: nop
+ IL_0116: ldstr "B.i: "
+ IL_011b: ldsfld int32 B::i
+ IL_0120: box [mscorlib]System.Int32
+ IL_0125: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_012a: call void [System.Console]System.Console::WriteLine(string)
+ IL_012f: nop
+ IL_0130: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_0135: call void [System.Console]System.Console::WriteLine(string)
+ IL_013a: nop
+ IL_013b: ldc.i4.0
+ IL_013c: stloc.0
+ IL_013d: nop
+ IL_013e: leave.s IL_0168
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_0140: pop
+ IL_0141: nop
+ IL_0142: ldstr "Caught expected exception 2nd time\n"
+ IL_0147: call void [System.Console]System.Console::WriteLine(string)
+ IL_014c: nop
+ IL_014d: nop
+ IL_014e: leave.s IL_0168
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_0150: stloc.1
+ IL_0151: nop
+ IL_0152: ldstr "Caught unexpected exception: "
+ IL_0157: ldloc.1
+ IL_0158: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_015d: call void [System.Console]System.Console::WriteLine(string)
+ IL_0162: nop
+ IL_0163: ldc.i4.0
+ IL_0164: stloc.0
+ IL_0165: nop
+ IL_0166: leave.s IL_0168
+
+ } // end handler
+ IL_0168: nop
+ IL_0169: ldloc.0
+ IL_016a: ldc.i4.0
+ IL_016b: ceq
+ IL_016d: stloc.3
+ IL_016e: ldloc.3
+ IL_016f: brtrue.s IL_0182
+
+ IL_0171: nop
+ IL_0172: ldstr "PASS"
+ IL_0177: call void [System.Console]System.Console::WriteLine(string)
+ IL_017c: nop
+ IL_017d: ldc.i4.s 100
+ IL_017f: stloc.2
+ IL_0180: br.s IL_0193
+
+ IL_0182: nop
+ IL_0183: ldstr "FAIL"
+ IL_0188: call void [System.Console]System.Console::WriteLine(string)
+ IL_018d: nop
+ IL_018e: ldc.i4.s 101
+ IL_0190: stloc.2
+ IL_0191: br.s IL_0193
+
+ IL_0193: ldloc.2
+ IL_0194: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file TypeLoadInitExcepBFI.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.ilproj
new file mode 100644
index 0000000000..a4da803e17
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/CctorThrowStaticFieldBFI.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorThrowStaticFieldBFI</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorThrowStaticFieldBFI.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.il
new file mode 100644
index 0000000000..600fd14e9c
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.il
@@ -0,0 +1,127 @@
+// 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.
+
+.assembly extern System.Console { }
+
+// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50110.00
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+
+
+// Metadata version: v2.0.50110
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly ResetGlobalFields
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module ResetGlobalFields.exe
+// MVID: {7BF531CB-7206-4C53-A779-930294C1158F}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public auto ansi A
+ extends [mscorlib]System.Object
+{
+ .field public static int32 s
+ .method public hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldc.i4.5
+ IL_0002: stsfld int32 A::s
+ IL_0007: ret
+ } // end of method A::.cctor
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 61 (0x3d)
+ .maxstack 2
+ .locals init (class A V_0,
+ int32 V_1,
+ bool V_2)
+ IL_0000: nop
+ IL_0001: newobj instance void A::.ctor()
+ IL_0006: stloc.0
+ IL_0007: ldc.i4.0
+ IL_0008: stsfld int32 A::s
+
+ // call .cctor explicitly
+ // global static field should be reset
+ call void A::.cctor()
+
+ IL_000d: ldsfld int32 A::s
+ IL_0012: ldc.i4.5
+ IL_0013: ceq
+ IL_0015: stloc.2
+ IL_0016: ldloc.2
+ IL_0017: brtrue.s IL_002a
+
+ IL_0019: nop
+ IL_001a: ldstr "FAIL: Global field wasn't reset"
+ IL_001f: call void [System.Console]System.Console::WriteLine(string)
+ IL_0024: nop
+ IL_0025: ldc.i4.s 101
+ IL_0027: stloc.1
+ IL_0028: br.s IL_003b
+
+ IL_002a: nop
+ IL_002b: ldstr "PASS: Global field was reset"
+ IL_0030: call void [System.Console]System.Console::WriteLine(string)
+ IL_0035: nop
+ IL_0036: ldc.i4.s 100
+ IL_0038: stloc.1
+ IL_0039: br.s IL_003b
+
+ IL_003b: ldloc.1
+ IL_003c: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file ResetGlobalFields.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.ilproj
new file mode 100644
index 0000000000..31e9c8550c
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/ResetGlobalFields.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>ResetGlobalFields</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="ResetGlobalFields.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.cs b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.cs
new file mode 100644
index 0000000000..859318e598
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.cs
@@ -0,0 +1,136 @@
+// 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.
+
+/*
+
+A .cctor has only one chance to run in any appdomain.
+If it fails, the 2nd time we try to access a static field we check if .cctor has been run. And it has, but failed so we fail again.
+
+Test throws an exception inside .cctor.
+Try to access a static field twice.
+Expected: Should return the same exception.
+
+*/
+
+using System;
+
+
+public class A
+{
+ public static int i;
+
+ static A()
+ {
+ Console.WriteLine("In A.cctor");
+
+ A.i = 5;
+
+ throw new Exception();
+ }
+}
+
+
+public struct B
+{
+ public static int i;
+
+ static B()
+ {
+ Console.WriteLine("In B.cctor");
+
+ B.i = 5;
+
+ throw new Exception();
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+ bool result = true;
+
+ try
+ {
+ Console.WriteLine("Accessing class's static field");
+ Console.WriteLine("A.i: " +A.i);
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+
+ try
+ {
+ Console.WriteLine("A.i: " +A.i);
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+
+ Console.WriteLine("Accessing struct's static field");
+ try
+ {
+ Console.WriteLine("B.i: " +B.i);
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 1st time");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 1st time: " + e);
+ result = false;
+ }
+
+
+ try
+ {
+ Console.WriteLine("B.i: " +B.i);
+ Console.WriteLine("Did not catch expected TypeInitializationException exception");
+ result = false;
+ }
+ catch (TypeInitializationException)
+ {
+ Console.WriteLine("Caught expected exception 2nd time\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Caught unexpected exception 2nd time: " + e);
+ result = false;
+ }
+
+ if (result)
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.csproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.csproj
new file mode 100644
index 0000000000..4063ef5e3c
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcep.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>TypeLoadInitExcep</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="TypeLoadInitExcep.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.il
new file mode 100644
index 0000000000..c0e0b14647
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.il
@@ -0,0 +1,346 @@
+// 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.
+
+.assembly extern System.Console { }
+
+// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+
+
+// Metadata version: v2.0.50103
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly TypeLoadInitExcep
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module TypeLoadInitExcep.exe
+// MVID: {A7BE6B3C-FF8D-43DB-B091-60CBA24AD082}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public auto ansi beforefieldinit A
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 24 (0x18)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In A.cctor"
+ IL_0006: call void [System.Console]System.Console::WriteLine(string)
+ IL_000b: nop
+ IL_000c: ldc.i4.5
+ IL_000d: stsfld int32 A::i
+ IL_0012: newobj instance void [mscorlib]System.Exception::.ctor()
+ IL_0017: throw
+ } // end of method A::.cctor
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+.class public sequential ansi sealed B
+ extends [mscorlib]System.ValueType
+{
+ .pack 0
+ .size 1
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 24 (0x18)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In B.cctor"
+ IL_0006: call void [System.Console]System.Console::WriteLine(string)
+ IL_000b: nop
+ IL_000c: ldc.i4.5
+ IL_000d: stsfld int32 B::i
+ IL_0012: newobj instance void [mscorlib]System.Exception::.ctor()
+ IL_0017: throw
+ } // end of method B::.cctor
+
+} // end of class B
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 405 (0x195)
+ .maxstack 2
+ .locals init (bool V_0,
+ class [mscorlib]System.Exception V_1,
+ int32 V_2,
+ bool V_3)
+ IL_0000: nop
+ IL_0001: ldc.i4.1
+ IL_0002: stloc.0
+ .try
+ {
+ IL_0003: nop
+ IL_0004: ldstr "Accessing class's static field"
+ IL_0009: call void [System.Console]System.Console::WriteLine(string)
+ IL_000e: nop
+ IL_000f: ldstr "A.i: "
+ IL_0014: ldsfld int32 A::i
+ IL_0019: box [mscorlib]System.Int32
+ IL_001e: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0023: call void [System.Console]System.Console::WriteLine(string)
+ IL_0028: nop
+ IL_0029: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_002e: call void [System.Console]System.Console::WriteLine(string)
+ IL_0033: nop
+ IL_0034: ldc.i4.0
+ IL_0035: stloc.0
+ IL_0036: nop
+ IL_0037: leave.s IL_0061
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_0039: pop
+ IL_003a: nop
+ IL_003b: ldstr "Caught expected exception 1st time"
+ IL_0040: call void [System.Console]System.Console::WriteLine(string)
+ IL_0045: nop
+ IL_0046: nop
+ IL_0047: leave.s IL_0061
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_0049: stloc.1
+ IL_004a: nop
+ IL_004b: ldstr "Caught unexpected exception: "
+ IL_0050: ldloc.1
+ IL_0051: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0056: call void [System.Console]System.Console::WriteLine(string)
+ IL_005b: nop
+ IL_005c: ldc.i4.0
+ IL_005d: stloc.0
+ IL_005e: nop
+ IL_005f: leave.s IL_0061
+
+ } // end handler
+ IL_0061: nop
+ .try
+ {
+ IL_0062: nop
+ IL_0063: ldstr "A.i: "
+ IL_0068: ldsfld int32 A::i
+ IL_006d: box [mscorlib]System.Int32
+ IL_0072: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0077: call void [System.Console]System.Console::WriteLine(string)
+ IL_007c: nop
+ IL_007d: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_0082: call void [System.Console]System.Console::WriteLine(string)
+ IL_0087: nop
+ IL_0088: ldc.i4.0
+ IL_0089: stloc.0
+ IL_008a: nop
+ IL_008b: leave.s IL_00b5
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_008d: pop
+ IL_008e: nop
+ IL_008f: ldstr "Caught expected exception 2nd time\n"
+ IL_0094: call void [System.Console]System.Console::WriteLine(string)
+ IL_0099: nop
+ IL_009a: nop
+ IL_009b: leave.s IL_00b5
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_009d: stloc.1
+ IL_009e: nop
+ IL_009f: ldstr "Caught unexpected exception: "
+ IL_00a4: ldloc.1
+ IL_00a5: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_00aa: call void [System.Console]System.Console::WriteLine(string)
+ IL_00af: nop
+ IL_00b0: ldc.i4.0
+ IL_00b1: stloc.0
+ IL_00b2: nop
+ IL_00b3: leave.s IL_00b5
+
+ } // end handler
+ IL_00b5: nop
+ IL_00b6: ldstr "Accessing struct's static field"
+ IL_00bb: call void [System.Console]System.Console::WriteLine(string)
+ IL_00c0: nop
+ .try
+ {
+ IL_00c1: nop
+ IL_00c2: ldstr "B.i: "
+ IL_00c7: ldsfld int32 B::i
+ IL_00cc: box [mscorlib]System.Int32
+ IL_00d1: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_00d6: call void [System.Console]System.Console::WriteLine(string)
+ IL_00db: nop
+ IL_00dc: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_00e1: call void [System.Console]System.Console::WriteLine(string)
+ IL_00e6: nop
+ IL_00e7: ldc.i4.0
+ IL_00e8: stloc.0
+ IL_00e9: nop
+ IL_00ea: leave.s IL_0114
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_00ec: pop
+ IL_00ed: nop
+ IL_00ee: ldstr "Caught expected exception 1st time"
+ IL_00f3: call void [System.Console]System.Console::WriteLine(string)
+ IL_00f8: nop
+ IL_00f9: nop
+ IL_00fa: leave.s IL_0114
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_00fc: stloc.1
+ IL_00fd: nop
+ IL_00fe: ldstr "Caught unexpected exception: "
+ IL_0103: ldloc.1
+ IL_0104: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0109: call void [System.Console]System.Console::WriteLine(string)
+ IL_010e: nop
+ IL_010f: ldc.i4.0
+ IL_0110: stloc.0
+ IL_0111: nop
+ IL_0112: leave.s IL_0114
+
+ } // end handler
+ IL_0114: nop
+ .try
+ {
+ IL_0115: nop
+ IL_0116: ldstr "B.i: "
+ IL_011b: ldsfld int32 B::i
+ IL_0120: box [mscorlib]System.Int32
+ IL_0125: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_012a: call void [System.Console]System.Console::WriteLine(string)
+ IL_012f: nop
+ IL_0130: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_0135: call void [System.Console]System.Console::WriteLine(string)
+ IL_013a: nop
+ IL_013b: ldc.i4.0
+ IL_013c: stloc.0
+ IL_013d: nop
+ IL_013e: leave.s IL_0168
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_0140: pop
+ IL_0141: nop
+ IL_0142: ldstr "Caught expected exception 2nd time\n"
+ IL_0147: call void [System.Console]System.Console::WriteLine(string)
+ IL_014c: nop
+ IL_014d: nop
+ IL_014e: leave.s IL_0168
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_0150: stloc.1
+ IL_0151: nop
+ IL_0152: ldstr "Caught unexpected exception: "
+ IL_0157: ldloc.1
+ IL_0158: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_015d: call void [System.Console]System.Console::WriteLine(string)
+ IL_0162: nop
+ IL_0163: ldc.i4.0
+ IL_0164: stloc.0
+ IL_0165: nop
+ IL_0166: leave.s IL_0168
+
+ } // end handler
+ IL_0168: nop
+ IL_0169: ldloc.0
+ IL_016a: ldc.i4.0
+ IL_016b: ceq
+ IL_016d: stloc.3
+ IL_016e: ldloc.3
+ IL_016f: brtrue.s IL_0182
+
+ IL_0171: nop
+ IL_0172: ldstr "PASS"
+ IL_0177: call void [System.Console]System.Console::WriteLine(string)
+ IL_017c: nop
+ IL_017d: ldc.i4.s 100
+ IL_017f: stloc.2
+ IL_0180: br.s IL_0193
+
+ IL_0182: nop
+ IL_0183: ldstr "FAIL"
+ IL_0188: call void [System.Console]System.Console::WriteLine(string)
+ IL_018d: nop
+ IL_018e: ldc.i4.s 101
+ IL_0190: stloc.2
+ IL_0191: br.s IL_0193
+
+ IL_0193: ldloc.2
+ IL_0194: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file TypeLoadInitExcepBFI.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.ilproj
new file mode 100644
index 0000000000..0f595c65c8
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/TypeLoadInitExcepBFI.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>TypeLoadInitExcepBFI</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="TypeLoadInitExcepBFI.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.il b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.il
new file mode 100644
index 0000000000..217be15789
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.il
@@ -0,0 +1,200 @@
+// 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.
+
+.assembly extern System.Console { }
+
+
+.assembly extern mscorlib {}
+
+.assembly UntrustedCodeBFI {}
+
+
+.class public auto ansi beforefieldinit B
+ extends [mscorlib]System.Object
+{
+ .field public static class C c_field
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 50 (0x32)
+ .maxstack 2
+ .locals init (class [mscorlib]System.Exception V_0)
+ IL_0000: nop
+ .try
+ {
+ IL_0001: nop
+ IL_0002: ldstr "In B.cctor"
+ IL_0007: call void [System.Console]System.Console::WriteLine(string)
+ IL_000c: nop
+ IL_000d: newobj instance void C::.ctor()
+ IL_0012: stsfld class C B::c_field
+ IL_0017: nop
+ IL_0018: leave.s IL_0030
+
+ } // end .try
+ catch [mscorlib]System.Exception
+ {
+ IL_001a: stloc.0
+ IL_001b: nop
+ IL_001c: ldstr "PASS: Caught exception : "
+ IL_0021: ldloc.0
+ IL_0022: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0027: call void [System.Console]System.Console::WriteLine(string)
+ IL_002c: nop
+ IL_002d: nop
+ IL_002e: leave.s IL_0030
+
+ } // end handler
+ IL_0030: nop
+ IL_0031: ret
+ } // end of method B::.cctor
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method B::.ctor
+
+} // end of class B
+
+.class public auto ansi beforefieldinit C
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 22 (0x16)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: nop
+ IL_0007: nop
+ IL_0008: ldc.i4.1
+ IL_0009: newobj instance void [mscorlib]System.Security.Permissions.FileIOPermission::.ctor(valuetype [mscorlib]System.Security.Permissions.PermissionState)
+ IL_000e: call instance void [mscorlib]System.Security.CodeAccessPermission::Demand()
+ IL_0013: nop
+ IL_0014: nop
+ IL_0015: ret
+ } // end of method C::.ctor
+
+} // end of class C
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 98 (0x62)
+ .maxstack 2
+ .locals init (class B V_0,
+ class A V_1,
+ class [mscorlib]System.Exception V_2,
+ int32 V_3)
+ IL_0000: nop
+ .try
+ {
+ IL_0001: nop
+ IL_0002: newobj instance void B::.ctor()
+ IL_0007: stloc.0
+ IL_0008: newobj instance void A::.ctor()
+ IL_000d: stloc.1
+ IL_000e: ldloc.1
+ IL_000f: callvirt instance void A::methodA()
+ IL_0014: nop
+ IL_0015: ldsfld class C B::c_field
+ IL_001a: callvirt instance string [mscorlib]System.Object::ToString()
+ IL_001f: call void [System.Console]System.Console::WriteLine(string)
+ IL_0024: nop
+ IL_0025: ldstr "FAIL: Did not catch NullReferenceException expecte"
+ + "d exception"
+ IL_002a: call void [System.Console]System.Console::WriteLine(string)
+ IL_002f: nop
+ IL_0030: ldc.i4.s 101
+ IL_0032: stloc.3
+ IL_0033: leave.s IL_005f
+
+ } // end .try
+ catch [mscorlib]System.NullReferenceException
+ {
+ IL_0035: pop
+ IL_0036: nop
+ IL_0037: ldstr "PASS: Caught expected NullReferenceException"
+ IL_003c: call void [System.Console]System.Console::WriteLine(string)
+ IL_0041: nop
+ IL_0042: ldc.i4.s 100
+ IL_0044: stloc.3
+ IL_0045: leave.s IL_005f
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_0047: stloc.2
+ IL_0048: nop
+ IL_0049: ldstr "PASS: Caught exception : "
+ IL_004e: ldloc.2
+ IL_004f: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0054: call void [System.Console]System.Console::WriteLine(string)
+ IL_0059: nop
+ IL_005a: ldc.i4.s 100
+ IL_005c: stloc.3
+ IL_005d: leave.s IL_005f
+
+ } // end handler
+ IL_005f: nop
+ IL_0060: ldloc.3
+ IL_0061: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+.class public auto ansi beforefieldinit A
+ extends [mscorlib]System.Object
+{
+ .permissionset deny
+ = {[mscorlib]System.Security.Permissions.FileIOPermissionAttribute = {property bool 'Unrestricted' = bool(true)}}
+ .method public hidebysig instance void
+ methodA() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldnull
+ IL_0002: stsfld class C B::c_field
+ IL_0007: ret
+ } // end of method A::methodA
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file UntrustedCodeBFI.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.ilproj
new file mode 100644
index 0000000000..53327a9555
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/UntrustedCodeBFI.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>UntrustedCodeBFI</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="UntrustedCodeBFI.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/app.config b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/app.config
new file mode 100644
index 0000000000..e5622f77ad
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/app.config
@@ -0,0 +1,27 @@
+<?xml version = "1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/project.json b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/project.json
new file mode 100644
index 0000000000..a2e84dc340
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CctorsWithSideEffects/project.json
@@ -0,0 +1,35 @@
+{
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816",
+ "System.Collections": "4.0.10",
+ "System.Collections.NonGeneric": "4.0.1-rc2-23816",
+ "System.Collections.Specialized": "4.0.1-rc2-23816",
+ "System.ComponentModel": "4.0.1-rc2-23816",
+ "System.Console": "4.0.0-rc2-23816",
+ "System.Diagnostics.Process": "4.1.0-rc2-23816",
+ "System.Globalization": "4.0.10",
+ "System.Globalization.Calendars": "4.0.0",
+ "System.IO": "4.0.10",
+ "System.IO.FileSystem": "4.0.0",
+ "System.IO.FileSystem.Primitives": "4.0.0",
+ "System.Linq": "4.0.1-rc2-23816",
+ "System.Linq.Queryable": "4.0.1-rc2-23816",
+ "System.Reflection": "4.0.10",
+ "System.Reflection.Primitives": "4.0.0",
+ "System.Runtime": "4.1.0-rc2-23816",
+ "System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.Handles": "4.0.0",
+ "System.Runtime.InteropServices": "4.1.0-rc2-23816",
+ "System.Runtime.Loader": "4.0.0-rc2-23816",
+ "System.Text.Encoding": "4.0.10",
+ "System.Threading": "4.0.10",
+ "System.Threading.Thread": "4.0.0-rc2-23816",
+ "System.Xml.ReaderWriter": "4.0.11-rc2-23816",
+ "System.Xml.XDocument": "4.0.11-rc2-23816",
+ "System.Xml.XmlDocument": "4.0.1-rc2-23816",
+ "System.Xml.XmlSerializer": "4.0.11-rc2-23816"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.cs b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.cs
new file mode 100644
index 0000000000..6e0da6a922
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.cs
@@ -0,0 +1,192 @@
+// 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.
+
+// A --> B --> C --> D --> E --> A
+// We should detect the deadlock and allow one thread to proceed (and see unitialized state).
+/*
+A --> B --> C --> D --> E --> A
+4 threads:
+Thread T1 starts initialization at A
+Thread T2 starts initialization at C
+Thread T3 starts initialization at D
+Thread T4 starts initialization at E
+
+A::.cctor sleeps for a few seconds so Thread T1 is blocked.
+C::.cctor sleeps for a few seconds so Thread T2 is blocked.
+D::.cctor sleeps for a few seconds so Thread T3 is blocked.
+
+In D.cctor: thread T3: E.i 0
+In C.cctor: thread T2: D.i 8
+In B.cctor: thread T1: C.i 7
+In A.cctor: thread T1: B.i 6
+In E.cctor: thread T4: A.i 5
+*/
+
+using System;
+using System.Threading;
+using System.Runtime.CompilerServices;
+public struct A
+{
+ public static int i;
+
+ static A()
+ {
+ Thread.Sleep(1000*2); // 1 second
+ Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i);
+ A.i = 5;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class B
+{
+ public static int i;
+
+ static B()
+ {
+ Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i);
+
+ B.i = 6;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public struct C
+{
+ public static int i;
+
+ static C()
+ {
+ Thread.Sleep(1000*2); // 1 second
+ Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i);
+ C.i = 7;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class D
+{
+ public static int i;
+
+ static D()
+ {
+ Thread.Sleep(1000*5); // 1 second
+ Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i);
+ D.i = 8;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public struct E
+{
+ public static int i;
+
+ static E()
+ {
+
+ Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i);
+ E.i = 9;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class Test
+{
+
+ public static void RunGetA()
+ {
+ A.SomeMethod();
+ }
+
+ public static void RunGetC()
+ {
+ C.SomeMethod();
+ }
+
+ public static void RunGetD()
+ {
+ D.SomeMethod();
+ }
+
+ public static void RunGetE()
+ {
+ E.SomeMethod();
+ }
+
+
+ public static int Main()
+ {
+
+ Thread t1 = new Thread(RunGetA);
+ t1.Name = "T1";
+ Thread t2 = new Thread(RunGetC);
+ t2.Name = "T2";
+ Thread t3 = new Thread(RunGetD);
+ t3.Name = "T3";
+ Thread t4 = new Thread(RunGetE);
+ t4.Name = "T4";
+
+
+
+ t1.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t2.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t3.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t4.Start();
+
+ t4.Join();
+ t3.Join();
+ t2.Join();
+ t1.Join();
+
+ // make sure that statics were set correctly.
+ if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 )
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.csproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.csproj
new file mode 100644
index 0000000000..4bf998c50a
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreads.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorFourThreads</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorFourThreads.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.il b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.il
new file mode 100644
index 0000000000..f567de543f
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.il
@@ -0,0 +1,463 @@
+// 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.
+
+.assembly extern System.Console { }
+
+// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+
+
+// Metadata version: v2.0.50103
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly CircularCctorFourThreads
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module CircularCctorFourThreads.exe
+// MVID: {DCC29B4C-2098-4C6E-A788-8284AF4F4942}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public sequential ansi sealed beforefieldinit A
+ extends [mscorlib]System.ValueType
+{
+ .pack 0
+ .size 1
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 50 (0x32)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldc.i4 0x7d0
+ IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_000b: nop
+ IL_000c: ldstr "In A.cctor: thread {0}: B.i {1}"
+ IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_001b: ldsfld int32 B::i
+ IL_0020: box [mscorlib]System.Int32
+ IL_0025: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_002a: nop
+ IL_002b: ldc.i4.5
+ IL_002c: stsfld int32 A::i
+ IL_0031: ret
+ } // end of method A::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method A::SomeMethod
+
+} // end of class A
+
+.class public auto ansi beforefieldinit B
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In B.cctor: thread {0}: C.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 C::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.6
+ IL_0021: stsfld int32 B::i
+ IL_0026: ret
+ } // end of method B::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method B::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method B::.ctor
+
+} // end of class B
+
+.class public sequential ansi sealed beforefieldinit C
+ extends [mscorlib]System.ValueType
+{
+ .pack 0
+ .size 1
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 50 (0x32)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldc.i4 0x7d0
+ IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_000b: nop
+ IL_000c: ldstr "In C.cctor: thread {0}: D.i {1}"
+ IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_001b: ldsfld int32 D::i
+ IL_0020: box [mscorlib]System.Int32
+ IL_0025: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_002a: nop
+ IL_002b: ldc.i4.7
+ IL_002c: stsfld int32 C::i
+ IL_0031: ret
+ } // end of method C::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method C::SomeMethod
+
+} // end of class C
+
+.class public auto ansi beforefieldinit D
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 50 (0x32)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldc.i4 0x1388
+ IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_000b: nop
+ IL_000c: ldstr "In D.cctor: thread {0}: E.i {1}"
+ IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_001b: ldsfld int32 E::i
+ IL_0020: box [mscorlib]System.Int32
+ IL_0025: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_002a: nop
+ IL_002b: ldc.i4.8
+ IL_002c: stsfld int32 D::i
+ IL_0031: ret
+ } // end of method D::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method D::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method D::.ctor
+
+} // end of class D
+
+.class public sequential ansi sealed beforefieldinit E
+ extends [mscorlib]System.ValueType
+{
+ .pack 0
+ .size 1
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 40 (0x28)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In E.cctor: thread {0}: A.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 A::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.s 9
+ IL_0022: stsfld int32 E::i
+ IL_0027: ret
+ } // end of method E::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method E::SomeMethod
+
+} // end of class E
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static void RunGetA() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void A::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetA
+
+ .method public hidebysig static void RunGetC() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void C::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetC
+
+ .method public hidebysig static void RunGetD() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void D::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetD
+
+ .method public hidebysig static void RunGetE() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void E::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetE
+
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 302 (0x12e)
+ .maxstack 3
+ .locals init (class [mscorlib]System.Threading.Thread V_0,
+ class [mscorlib]System.Threading.Thread V_1,
+ class [mscorlib]System.Threading.Thread V_2,
+ class [mscorlib]System.Threading.Thread V_3,
+ int32 V_4,
+ bool V_5)
+ IL_0000: nop
+ IL_0001: ldnull
+ IL_0002: ldftn void Test::RunGetA()
+ IL_0008: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_000d: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_0012: stloc.0
+ IL_0013: ldloc.0
+ IL_0014: ldstr "T1"
+ IL_0019: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_001e: nop
+ IL_001f: ldnull
+ IL_0020: ldftn void Test::RunGetC()
+ IL_0026: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_002b: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_0030: stloc.1
+ IL_0031: ldloc.1
+ IL_0032: ldstr "T2"
+ IL_0037: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_003c: nop
+ IL_003d: ldnull
+ IL_003e: ldftn void Test::RunGetD()
+ IL_0044: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_0049: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_004e: stloc.2
+ IL_004f: ldloc.2
+ IL_0050: ldstr "T3"
+ IL_0055: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_005a: nop
+ IL_005b: ldnull
+ IL_005c: ldftn void Test::RunGetE()
+ IL_0062: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_0067: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_006c: stloc.3
+ IL_006d: ldloc.3
+ IL_006e: ldstr "T4"
+ IL_0073: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_0078: nop
+ IL_0079: ldloc.0
+ IL_007a: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_007f: nop
+ IL_0080: ldc.i4 0x3e8
+ IL_0085: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_008a: nop
+ IL_008b: ldloc.1
+ IL_008c: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0091: nop
+ IL_0092: ldc.i4 0x3e8
+ IL_0097: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_009c: nop
+ IL_009d: ldloc.2
+ IL_009e: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_00a3: nop
+ IL_00a4: ldc.i4 0x3e8
+ IL_00a9: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_00ae: nop
+ IL_00af: ldloc.3
+ IL_00b0: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_00b5: nop
+ IL_00b6: ldloc.3
+ IL_00b7: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_00bc: nop
+ IL_00bd: ldloc.2
+ IL_00be: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_00c3: nop
+ IL_00c4: ldloc.1
+ IL_00c5: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_00ca: nop
+ IL_00cb: ldloc.0
+ IL_00cc: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_00d1: nop
+ IL_00d2: ldsfld int32 A::i
+ IL_00d7: ldc.i4.5
+ IL_00d8: bne.un.s IL_0100
+
+ IL_00da: ldsfld int32 B::i
+ IL_00df: ldc.i4.6
+ IL_00e0: bne.un.s IL_0100
+
+ IL_00e2: ldsfld int32 C::i
+ IL_00e7: ldc.i4.7
+ IL_00e8: bne.un.s IL_0100
+
+ IL_00ea: ldsfld int32 D::i
+ IL_00ef: ldc.i4.8
+ IL_00f0: bne.un.s IL_0100
+
+ IL_00f2: ldsfld int32 E::i
+ IL_00f7: ldc.i4.s 9
+ IL_00f9: ceq
+ IL_00fb: ldc.i4.0
+ IL_00fc: ceq
+ IL_00fe: br.s IL_0101
+
+ IL_0100: ldc.i4.1
+ IL_0101: stloc.s V_5
+ IL_0103: ldloc.s V_5
+ IL_0105: brtrue.s IL_0119
+
+ IL_0107: nop
+ IL_0108: ldstr "PASS"
+ IL_010d: call void [System.Console]System.Console::WriteLine(string)
+ IL_0112: nop
+ IL_0113: ldc.i4.s 100
+ IL_0115: stloc.s V_4
+ IL_0117: br.s IL_012b
+
+ IL_0119: nop
+ IL_011a: ldstr "FAIL"
+ IL_011f: call void [System.Console]System.Console::WriteLine(string)
+ IL_0124: nop
+ IL_0125: ldc.i4.s 101
+ IL_0127: stloc.s V_4
+ IL_0129: br.s IL_012b
+
+ IL_012b: ldloc.s V_4
+ IL_012d: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file CircularCctorFourThreads.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.ilproj
new file mode 100644
index 0000000000..7c1c2df15a
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorFourThreadsBFI.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorFourThreadsBFI</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorFourThreadsBFI.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.cs b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.cs
new file mode 100644
index 0000000000..da06e4a15e
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.cs
@@ -0,0 +1,163 @@
+// 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.
+
+/*
+A --> B --> C --> D --> E --> A
+3 threads: Thread T1 starts initialization at A, thread T2 starts initialization at C, and thread T3 starts initialization at E.
+This should form a three thread deadlock, which we will detect and allow one of the three threads to proceed, breaking the deadlock.
+*/
+
+using System;
+using System.Threading;
+using System.Runtime.CompilerServices;
+public class A
+{
+ public static int i;
+
+ static A()
+ {
+
+ Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i);
+ A.i = 5;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class B
+{
+ public static int i;
+
+ static B()
+ {
+
+
+ Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i);
+ B.i = 6;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class C
+{
+ public static int i;
+
+ static C()
+ {
+ Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i);
+ C.i = 7;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class D
+{
+ public static int i;
+
+ static D()
+ {
+ Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i);
+ D.i = 8;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class E
+{
+ public static int i;
+
+ static E()
+ {
+ Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i);
+ E.i = 9;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class Test
+{
+
+ public static void RunGetA()
+ {
+ A.SomeMethod();
+ }
+
+ public static void RunGetC()
+ {
+ C.SomeMethod();
+ }
+
+ public static void RunGetE()
+ {
+ E.SomeMethod();
+ }
+
+
+ public static int Main()
+ {
+ Thread t1 = new Thread(RunGetA);
+ t1.Name = "T1";
+ Thread t2 = new Thread(RunGetC);
+ t2.Name = "T2";
+ Thread t3 = new Thread(RunGetE);
+ t3.Name = "T3";
+
+ t1.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t2.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t3.Start();
+
+ t3.Join();
+ t2.Join();
+ t1.Join();
+
+
+ // make sure that statics were set correctly
+ if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 )
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.csproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.csproj
new file mode 100644
index 0000000000..1b61083bc9
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorThreeThreads01</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorThreeThreads01.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.il b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.il
new file mode 100644
index 0000000000..e3bf0905b1
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.il
@@ -0,0 +1,448 @@
+// 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.
+
+.assembly extern System.Console { }
+
+// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+
+
+// Metadata version: v2.0.50103
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly CircularCctorThreeThreads01
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module CircularCctorThreeThreads01.exe
+// MVID: {391DADEC-FC20-4965-82DE-5A0027055F7B}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public auto ansi beforefieldinit A
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In A.cctor: thread {0}: B.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 B::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.5
+ IL_0021: stsfld int32 A::i
+ IL_0026: ret
+ } // end of method A::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method A::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+.class public auto ansi beforefieldinit B
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In B.cctor: thread {0}: C.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 C::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.6
+ IL_0021: stsfld int32 B::i
+ IL_0026: ret
+ } // end of method B::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method B::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method B::.ctor
+
+} // end of class B
+
+.class public auto ansi beforefieldinit C
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In C.cctor: thread {0}: D.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 D::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.7
+ IL_0021: stsfld int32 C::i
+ IL_0026: ret
+ } // end of method C::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method C::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method C::.ctor
+
+} // end of class C
+
+.class public auto ansi beforefieldinit D
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In D.cctor: thread {0}: E.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 E::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.8
+ IL_0021: stsfld int32 D::i
+ IL_0026: ret
+ } // end of method D::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method D::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method D::.ctor
+
+} // end of class D
+
+.class public auto ansi beforefieldinit E
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 40 (0x28)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In E.cctor: thread {0}: A.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 A::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.s 9
+ IL_0022: stsfld int32 E::i
+ IL_0027: ret
+ } // end of method E::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method E::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method E::.ctor
+
+} // end of class E
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static void RunGetA() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void A::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetA
+
+ .method public hidebysig static void RunGetC() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void C::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetC
+
+ .method public hidebysig static void RunGetE() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void E::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetE
+
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 244 (0xf4)
+ .maxstack 3
+ .locals init (class [mscorlib]System.Threading.Thread V_0,
+ class [mscorlib]System.Threading.Thread V_1,
+ class [mscorlib]System.Threading.Thread V_2,
+ int32 V_3,
+ bool V_4)
+ IL_0000: nop
+ IL_0001: ldnull
+ IL_0002: ldftn void Test::RunGetA()
+ IL_0008: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_000d: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_0012: stloc.0
+ IL_0013: ldloc.0
+ IL_0014: ldstr "T1"
+ IL_0019: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_001e: nop
+ IL_001f: ldnull
+ IL_0020: ldftn void Test::RunGetC()
+ IL_0026: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_002b: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_0030: stloc.1
+ IL_0031: ldloc.1
+ IL_0032: ldstr "T2"
+ IL_0037: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_003c: nop
+ IL_003d: ldnull
+ IL_003e: ldftn void Test::RunGetE()
+ IL_0044: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_0049: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_004e: stloc.2
+ IL_004f: ldloc.2
+ IL_0050: ldstr "T3"
+ IL_0055: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_005a: nop
+ IL_005b: ldloc.0
+ IL_005c: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0061: nop
+ IL_0062: ldc.i4 0x3e8
+ IL_0067: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_006c: nop
+ IL_006d: ldloc.1
+ IL_006e: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0073: nop
+ IL_0074: ldc.i4 0x3e8
+ IL_0079: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_007e: nop
+ IL_007f: ldloc.2
+ IL_0080: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0085: nop
+ IL_0086: ldloc.2
+ IL_0087: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_008c: nop
+ IL_008d: ldloc.1
+ IL_008e: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_0093: nop
+ IL_0094: ldloc.0
+ IL_0095: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_009a: nop
+ IL_009b: ldsfld int32 A::i
+ IL_00a0: ldc.i4.5
+ IL_00a1: bne.un.s IL_00c9
+
+ IL_00a3: ldsfld int32 B::i
+ IL_00a8: ldc.i4.6
+ IL_00a9: bne.un.s IL_00c9
+
+ IL_00ab: ldsfld int32 C::i
+ IL_00b0: ldc.i4.7
+ IL_00b1: bne.un.s IL_00c9
+
+ IL_00b3: ldsfld int32 D::i
+ IL_00b8: ldc.i4.8
+ IL_00b9: bne.un.s IL_00c9
+
+ IL_00bb: ldsfld int32 E::i
+ IL_00c0: ldc.i4.s 9
+ IL_00c2: ceq
+ IL_00c4: ldc.i4.0
+ IL_00c5: ceq
+ IL_00c7: br.s IL_00ca
+
+ IL_00c9: ldc.i4.1
+ IL_00ca: stloc.s V_4
+ IL_00cc: ldloc.s V_4
+ IL_00ce: brtrue.s IL_00e1
+
+ IL_00d0: nop
+ IL_00d1: ldstr "PASS"
+ IL_00d6: call void [System.Console]System.Console::WriteLine(string)
+ IL_00db: nop
+ IL_00dc: ldc.i4.s 100
+ IL_00de: stloc.3
+ IL_00df: br.s IL_00f2
+
+ IL_00e1: nop
+ IL_00e2: ldstr "FAIL"
+ IL_00e7: call void [System.Console]System.Console::WriteLine(string)
+ IL_00ec: nop
+ IL_00ed: ldc.i4.s 101
+ IL_00ef: stloc.3
+ IL_00f0: br.s IL_00f2
+
+ IL_00f2: ldloc.3
+ IL_00f3: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file CircularCctorThreeThreads01.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.ilproj
new file mode 100644
index 0000000000..0cec84e064
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads01BFI.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorThreeThreads01BFI</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorThreeThreads01BFI.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.cs b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.cs
new file mode 100644
index 0000000000..e92a39bde7
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.cs
@@ -0,0 +1,177 @@
+// 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.
+
+/*
+A --> B --> C --> D --> E --> A
+3 threads: Thread T1 starts initialization at A, thread T2 starts initialization at C, and thread T3 starts initialization at E.
+A::.cctor sleeps for a few seconds so Thread T1 is blocked.
+T2 invokes C::.cctor ' D::.cctor ' E::.cctor ' A::.cctor at which point T2 becomes blocked waiting for T1.
+T3 is blocked because T2 is in E::.cctor.
+T1 becomes unblocked, invokes B::.cctor, wants to invoke C::.cctor but, T2 is in C::.cctor so we get a 3 thread deadlock.
+We detect the deadlock and allow T1 to see C.i uninitialized state.
+
+In B.cctor: thread T1: C.i 0
+In A.cctor: thread T1: B.i 6
+In E.cctor: thread T2: A.i 5
+In D.cctor: thread T2: E.i 9
+In C.cctor: thread T2: D.i 8
+*/
+
+using System;
+using System.Threading;
+using System.Runtime.CompilerServices;
+public class A
+{
+ public static int i;
+
+ static A()
+ {
+
+ Thread.Sleep(1000*2); // 1 second
+ Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i);
+ A.i = 5;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class B
+{
+ public static int i;
+
+ static B()
+ {
+
+
+ Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i);
+ B.i = 6;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class C
+{
+ public static int i;
+
+ static C()
+ {
+ Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i);
+ C.i = 7;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class D
+{
+ public static int i;
+
+
+ static D()
+ {
+ Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i);
+ D.i = 8;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class E
+{
+ public static int i;
+
+ static E()
+ {
+ Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i);
+ E.i = 9;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class Test
+{
+
+ public static void RunGetA()
+ {
+ A.SomeMethod();
+ }
+
+ public static void RunGetC()
+ {
+ C.SomeMethod();
+ }
+
+ public static void RunGetE()
+ {
+ E.SomeMethod();
+ }
+
+
+ public static int Main()
+ {
+
+ Thread t1 = new Thread(RunGetA);
+ t1.Name = "T1";
+ Thread t2 = new Thread(RunGetC);
+ t2.Name = "T2";
+ Thread t3 = new Thread(RunGetE);
+ t3.Name = "T3";
+
+
+
+ t1.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t2.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t3.Start();
+
+ t3.Join();
+ t2.Join();
+ t1.Join();
+
+ // make sure that statics were set correctly.
+ if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 )
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.csproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.csproj
new file mode 100644
index 0000000000..dbc05d5d3a
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorThreeThreads02</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorThreeThreads02.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.il b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.il
new file mode 100644
index 0000000000..5c75d8ff5c
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.il
@@ -0,0 +1,451 @@
+// 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.
+
+.assembly extern System.Console { }
+
+// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+
+
+// Metadata version: v2.0.50103
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly CircularCctorThreeThreads02
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module CircularCctorThreeThreads02.exe
+// MVID: {D90A3A61-FEDA-4DC1-A90B-0FEBC5C34B33}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public auto ansi beforefieldinit A
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 50 (0x32)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldc.i4 0x7d0
+ IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_000b: nop
+ IL_000c: ldstr "In A.cctor: thread {0}: B.i {1}"
+ IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_001b: ldsfld int32 B::i
+ IL_0020: box [mscorlib]System.Int32
+ IL_0025: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_002a: nop
+ IL_002b: ldc.i4.5
+ IL_002c: stsfld int32 A::i
+ IL_0031: ret
+ } // end of method A::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method A::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+.class public auto ansi beforefieldinit B
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In B.cctor: thread {0}: C.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 C::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.6
+ IL_0021: stsfld int32 B::i
+ IL_0026: ret
+ } // end of method B::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method B::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method B::.ctor
+
+} // end of class B
+
+.class public auto ansi beforefieldinit C
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In C.cctor: thread {0}: D.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 D::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.7
+ IL_0021: stsfld int32 C::i
+ IL_0026: ret
+ } // end of method C::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method C::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method C::.ctor
+
+} // end of class C
+
+.class public auto ansi beforefieldinit D
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In D.cctor: thread {0}: E.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 E::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.8
+ IL_0021: stsfld int32 D::i
+ IL_0026: ret
+ } // end of method D::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method D::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method D::.ctor
+
+} // end of class D
+
+.class public auto ansi beforefieldinit E
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 40 (0x28)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In E.cctor: thread {0}: A.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 A::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.s 9
+ IL_0022: stsfld int32 E::i
+ IL_0027: ret
+ } // end of method E::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method E::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method E::.ctor
+
+} // end of class E
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static void RunGetA() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void A::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetA
+
+ .method public hidebysig static void RunGetC() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void C::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetC
+
+ .method public hidebysig static void RunGetE() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void E::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetE
+
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 244 (0xf4)
+ .maxstack 3
+ .locals init (class [mscorlib]System.Threading.Thread V_0,
+ class [mscorlib]System.Threading.Thread V_1,
+ class [mscorlib]System.Threading.Thread V_2,
+ int32 V_3,
+ bool V_4)
+ IL_0000: nop
+ IL_0001: ldnull
+ IL_0002: ldftn void Test::RunGetA()
+ IL_0008: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_000d: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_0012: stloc.0
+ IL_0013: ldloc.0
+ IL_0014: ldstr "T1"
+ IL_0019: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_001e: nop
+ IL_001f: ldnull
+ IL_0020: ldftn void Test::RunGetC()
+ IL_0026: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_002b: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_0030: stloc.1
+ IL_0031: ldloc.1
+ IL_0032: ldstr "T2"
+ IL_0037: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_003c: nop
+ IL_003d: ldnull
+ IL_003e: ldftn void Test::RunGetE()
+ IL_0044: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_0049: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_004e: stloc.2
+ IL_004f: ldloc.2
+ IL_0050: ldstr "T3"
+ IL_0055: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_005a: nop
+ IL_005b: ldloc.0
+ IL_005c: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0061: nop
+ IL_0062: ldc.i4 0x3e8
+ IL_0067: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_006c: nop
+ IL_006d: ldloc.1
+ IL_006e: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0073: nop
+ IL_0074: ldc.i4 0x3e8
+ IL_0079: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_007e: nop
+ IL_007f: ldloc.2
+ IL_0080: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0085: nop
+ IL_0086: ldloc.2
+ IL_0087: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_008c: nop
+ IL_008d: ldloc.1
+ IL_008e: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_0093: nop
+ IL_0094: ldloc.0
+ IL_0095: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_009a: nop
+ IL_009b: ldsfld int32 A::i
+ IL_00a0: ldc.i4.5
+ IL_00a1: bne.un.s IL_00c9
+
+ IL_00a3: ldsfld int32 B::i
+ IL_00a8: ldc.i4.6
+ IL_00a9: bne.un.s IL_00c9
+
+ IL_00ab: ldsfld int32 C::i
+ IL_00b0: ldc.i4.7
+ IL_00b1: bne.un.s IL_00c9
+
+ IL_00b3: ldsfld int32 D::i
+ IL_00b8: ldc.i4.8
+ IL_00b9: bne.un.s IL_00c9
+
+ IL_00bb: ldsfld int32 E::i
+ IL_00c0: ldc.i4.s 9
+ IL_00c2: ceq
+ IL_00c4: ldc.i4.0
+ IL_00c5: ceq
+ IL_00c7: br.s IL_00ca
+
+ IL_00c9: ldc.i4.1
+ IL_00ca: stloc.s V_4
+ IL_00cc: ldloc.s V_4
+ IL_00ce: brtrue.s IL_00e1
+
+ IL_00d0: nop
+ IL_00d1: ldstr "PASS"
+ IL_00d6: call void [System.Console]System.Console::WriteLine(string)
+ IL_00db: nop
+ IL_00dc: ldc.i4.s 100
+ IL_00de: stloc.3
+ IL_00df: br.s IL_00f2
+
+ IL_00e1: nop
+ IL_00e2: ldstr "FAIL"
+ IL_00e7: call void [System.Console]System.Console::WriteLine(string)
+ IL_00ec: nop
+ IL_00ed: ldc.i4.s 101
+ IL_00ef: stloc.3
+ IL_00f0: br.s IL_00f2
+
+ IL_00f2: ldloc.3
+ IL_00f3: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file CircularCctorThreeThreads02BFI.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.ilproj
new file mode 100644
index 0000000000..4607cad8b0
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads02BFI.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorThreeThreads02BFI</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorThreeThreads02BFI.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.cs b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.cs
new file mode 100644
index 0000000000..5b6b090709
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.cs
@@ -0,0 +1,180 @@
+// 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.
+
+/*
+A --> B --> C --> D --> E --> A
+3 threads: Thread T1 starts initialization at A, thread T2 starts initialization at C, and thread T3 starts initialization at E.
+A::.cctor sleeps for a few seconds so Thread T1 is blocked.
+C::.cctor sleeps for a few seconds so Thread T2 is blocked.
+
+T3 invokes E::.cctor and blocks because T1 is in A::.cctor.
+T1 becomes unblocked, invokes B::.cctor, tries to invoke C::.cctor and becomes blocked (because C::.cctor is used by T2).
+T2 becomes unblocked , invokes D.::cctor, tries to invokes E::.cctor at which point we get 3 thread deadlock since T3 is waiting for T1 and T1 is waiting for T2 and T2 is waiting for T3.
+We detect the deadlock and allow T2 to see E.i uninitialized state.
+
+In D.cctor: thread T2: E.i 0
+In C.cctor: thread T2: D.i 8
+In B.cctor: thread T1: C.i 7
+In A.cctor: thread T1: B.i 6
+In E.cctor: thread T3: A.i 5
+*/
+
+using System;
+using System.Threading;
+using System.Runtime.CompilerServices;
+public class A
+{
+ public static int i;
+
+ static A()
+ {
+
+ Thread.Sleep(1000*2); // 1 second
+ Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i);
+ A.i = 5;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class B
+{
+ public static int i;
+
+ static B()
+ {
+
+
+ Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i);
+ B.i = 6;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class C
+{
+ public static int i;
+
+ static C()
+ {
+
+ Thread.Sleep(1000*2); // 1 second
+ Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i);
+ C.i = 7;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class D
+{
+ public static int i;
+
+ static D()
+ {
+ Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i);
+ D.i = 8;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class E
+{
+ public static int i;
+
+ static E()
+ {
+ Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i);
+ E.i = 9;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class Test
+{
+
+ public static void RunGetA()
+ {
+ A.SomeMethod();
+ }
+
+ public static void RunGetC()
+ {
+ C.SomeMethod();
+ }
+
+ public static void RunGetE()
+ {
+ E.SomeMethod();
+ }
+
+
+ public static int Main()
+ {
+
+ Thread t1 = new Thread(RunGetA);
+ t1.Name = "T1";
+ Thread t2 = new Thread(RunGetC);
+ t2.Name = "T2";
+ Thread t3 = new Thread(RunGetE);
+ t3.Name = "T3";
+
+
+
+ t1.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t2.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t3.Start();
+
+ t3.Join();
+ t2.Join();
+ t1.Join();
+
+ // make sure that statics were set correctly.
+ if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 )
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.csproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.csproj
new file mode 100644
index 0000000000..d6d7447389
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorThreeThreads03</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorThreeThreads03.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.il b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.il
new file mode 100644
index 0000000000..51d9a3bbe7
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.il
@@ -0,0 +1,454 @@
+// 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.
+
+.assembly extern System.Console { }
+
+// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+
+
+// Metadata version: v2.0.50103
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly CircularCctorThreeThreads03
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module CircularCctorThreeThreads03.exe
+// MVID: {11FF80B2-E180-44EE-815F-912DD3D6227D}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public auto ansi beforefieldinit A
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 50 (0x32)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldc.i4 0x7d0
+ IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_000b: nop
+ IL_000c: ldstr "In A.cctor: thread {0}: B.i {1}"
+ IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_001b: ldsfld int32 B::i
+ IL_0020: box [mscorlib]System.Int32
+ IL_0025: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_002a: nop
+ IL_002b: ldc.i4.5
+ IL_002c: stsfld int32 A::i
+ IL_0031: ret
+ } // end of method A::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method A::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+.class public auto ansi beforefieldinit B
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In B.cctor: thread {0}: C.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 C::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.6
+ IL_0021: stsfld int32 B::i
+ IL_0026: ret
+ } // end of method B::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method B::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method B::.ctor
+
+} // end of class B
+
+.class public auto ansi beforefieldinit C
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 50 (0x32)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldc.i4 0x7d0
+ IL_0006: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_000b: nop
+ IL_000c: ldstr "In C.cctor: thread {0}: D.i {1}"
+ IL_0011: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_0016: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_001b: ldsfld int32 D::i
+ IL_0020: box [mscorlib]System.Int32
+ IL_0025: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_002a: nop
+ IL_002b: ldc.i4.7
+ IL_002c: stsfld int32 C::i
+ IL_0031: ret
+ } // end of method C::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method C::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method C::.ctor
+
+} // end of class C
+
+.class public auto ansi beforefieldinit D
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 39 (0x27)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In D.cctor: thread {0}: E.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 E::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.8
+ IL_0021: stsfld int32 D::i
+ IL_0026: ret
+ } // end of method D::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method D::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method D::.ctor
+
+} // end of class D
+
+.class public auto ansi beforefieldinit E
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 40 (0x28)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In E.cctor: thread {0}: A.i {1}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: ldsfld int32 A::i
+ IL_0015: box [mscorlib]System.Int32
+ IL_001a: call void [System.Console]System.Console::WriteLine(string,
+ object,
+ object)
+ IL_001f: nop
+ IL_0020: ldc.i4.s 9
+ IL_0022: stsfld int32 E::i
+ IL_0027: ret
+ } // end of method E::.cctor
+
+ .method public hidebysig static void SomeMethod() cil managed noinlining
+ {
+ // Code size 23 (0x17)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In MyClass.SomeMethod(): thread {0}"
+ IL_0006: call class [mscorlib]System.Threading.Thread [mscorlib]System.Threading.Thread::get_CurrentThread()
+ IL_000b: callvirt instance string [mscorlib]System.Threading.Thread::get_Name()
+ IL_0010: call void [System.Console]System.Console::WriteLine(string,
+ object)
+ IL_0015: nop
+ IL_0016: ret
+ } // end of method E::SomeMethod
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method E::.ctor
+
+} // end of class E
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static void RunGetA() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void A::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetA
+
+ .method public hidebysig static void RunGetC() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void C::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetC
+
+ .method public hidebysig static void RunGetE() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: call void E::SomeMethod()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Test::RunGetE
+
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 244 (0xf4)
+ .maxstack 3
+ .locals init (class [mscorlib]System.Threading.Thread V_0,
+ class [mscorlib]System.Threading.Thread V_1,
+ class [mscorlib]System.Threading.Thread V_2,
+ int32 V_3,
+ bool V_4)
+ IL_0000: nop
+ IL_0001: ldnull
+ IL_0002: ldftn void Test::RunGetA()
+ IL_0008: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_000d: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_0012: stloc.0
+ IL_0013: ldloc.0
+ IL_0014: ldstr "T1"
+ IL_0019: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_001e: nop
+ IL_001f: ldnull
+ IL_0020: ldftn void Test::RunGetC()
+ IL_0026: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_002b: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_0030: stloc.1
+ IL_0031: ldloc.1
+ IL_0032: ldstr "T2"
+ IL_0037: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_003c: nop
+ IL_003d: ldnull
+ IL_003e: ldftn void Test::RunGetE()
+ IL_0044: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object,
+ native int)
+ IL_0049: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
+ IL_004e: stloc.2
+ IL_004f: ldloc.2
+ IL_0050: ldstr "T3"
+ IL_0055: callvirt instance void [mscorlib]System.Threading.Thread::set_Name(string)
+ IL_005a: nop
+ IL_005b: ldloc.0
+ IL_005c: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0061: nop
+ IL_0062: ldc.i4 0x3e8
+ IL_0067: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_006c: nop
+ IL_006d: ldloc.1
+ IL_006e: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0073: nop
+ IL_0074: ldc.i4 0x3e8
+ IL_0079: call void [mscorlib]System.Threading.Thread::Sleep(int32)
+ IL_007e: nop
+ IL_007f: ldloc.2
+ IL_0080: callvirt instance void [mscorlib]System.Threading.Thread::Start()
+ IL_0085: nop
+ IL_0086: ldloc.2
+ IL_0087: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_008c: nop
+ IL_008d: ldloc.1
+ IL_008e: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_0093: nop
+ IL_0094: ldloc.0
+ IL_0095: callvirt instance void [mscorlib]System.Threading.Thread::Join()
+ IL_009a: nop
+ IL_009b: ldsfld int32 A::i
+ IL_00a0: ldc.i4.5
+ IL_00a1: bne.un.s IL_00c9
+
+ IL_00a3: ldsfld int32 B::i
+ IL_00a8: ldc.i4.6
+ IL_00a9: bne.un.s IL_00c9
+
+ IL_00ab: ldsfld int32 C::i
+ IL_00b0: ldc.i4.7
+ IL_00b1: bne.un.s IL_00c9
+
+ IL_00b3: ldsfld int32 D::i
+ IL_00b8: ldc.i4.8
+ IL_00b9: bne.un.s IL_00c9
+
+ IL_00bb: ldsfld int32 E::i
+ IL_00c0: ldc.i4.s 9
+ IL_00c2: ceq
+ IL_00c4: ldc.i4.0
+ IL_00c5: ceq
+ IL_00c7: br.s IL_00ca
+
+ IL_00c9: ldc.i4.1
+ IL_00ca: stloc.s V_4
+ IL_00cc: ldloc.s V_4
+ IL_00ce: brtrue.s IL_00e1
+
+ IL_00d0: nop
+ IL_00d1: ldstr "PASS"
+ IL_00d6: call void [System.Console]System.Console::WriteLine(string)
+ IL_00db: nop
+ IL_00dc: ldc.i4.s 100
+ IL_00de: stloc.3
+ IL_00df: br.s IL_00f2
+
+ IL_00e1: nop
+ IL_00e2: ldstr "FAIL"
+ IL_00e7: call void [System.Console]System.Console::WriteLine(string)
+ IL_00ec: nop
+ IL_00ed: ldc.i4.s 101
+ IL_00ef: stloc.3
+ IL_00f0: br.s IL_00f2
+
+ IL_00f2: ldloc.3
+ IL_00f3: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file CircularCctorThreeThreads03BFI.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.ilproj
new file mode 100644
index 0000000000..53f3c3e5ef
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/CircularCctorThreeThreads03BFI.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorThreeThreads03BFI</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorThreeThreads03BFI.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/app.config b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/app.config
new file mode 100644
index 0000000000..e5622f77ad
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/app.config
@@ -0,0 +1,27 @@
+<?xml version = "1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CircularCctors/project.json b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/project.json
new file mode 100644
index 0000000000..a2e84dc340
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CircularCctors/project.json
@@ -0,0 +1,35 @@
+{
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816",
+ "System.Collections": "4.0.10",
+ "System.Collections.NonGeneric": "4.0.1-rc2-23816",
+ "System.Collections.Specialized": "4.0.1-rc2-23816",
+ "System.ComponentModel": "4.0.1-rc2-23816",
+ "System.Console": "4.0.0-rc2-23816",
+ "System.Diagnostics.Process": "4.1.0-rc2-23816",
+ "System.Globalization": "4.0.10",
+ "System.Globalization.Calendars": "4.0.0",
+ "System.IO": "4.0.10",
+ "System.IO.FileSystem": "4.0.0",
+ "System.IO.FileSystem.Primitives": "4.0.0",
+ "System.Linq": "4.0.1-rc2-23816",
+ "System.Linq.Queryable": "4.0.1-rc2-23816",
+ "System.Reflection": "4.0.10",
+ "System.Reflection.Primitives": "4.0.0",
+ "System.Runtime": "4.1.0-rc2-23816",
+ "System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.Handles": "4.0.0",
+ "System.Runtime.InteropServices": "4.1.0-rc2-23816",
+ "System.Runtime.Loader": "4.0.0-rc2-23816",
+ "System.Text.Encoding": "4.0.10",
+ "System.Threading": "4.0.10",
+ "System.Threading.Thread": "4.0.0-rc2-23816",
+ "System.Xml.ReaderWriter": "4.0.11-rc2-23816",
+ "System.Xml.XDocument": "4.0.11-rc2-23816",
+ "System.Xml.XmlDocument": "4.0.1-rc2-23816",
+ "System.Xml.XmlSerializer": "4.0.11-rc2-23816"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.il b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.il
new file mode 100644
index 0000000000..255282576c
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.il
@@ -0,0 +1,346 @@
+// 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.
+
+.assembly extern System.Console { }
+
+// Microsoft (R) .NET Framework IL Disassembler. Version 2.0.50103.00
+// Copyright (C) Microsoft Corporation. All rights reserved.
+
+
+
+// Metadata version: v2.0.50103
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+.assembly CctorThrowStaticFieldBFI
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.module CctorThrowStaticFieldBFI.exe
+// MVID: {A7BE6B3C-FF8D-43DB-B091-60CBA24AD082}
+.imagebase 0x00400000
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003 // WINDOWS_CUI
+.corflags 0x00000001 // ILONLY
+// Image base: 0x03090000
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class public auto ansi beforefieldinit A
+ extends [mscorlib]System.Object
+{
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 24 (0x18)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In A.cctor"
+ IL_0006: call void [System.Console]System.Console::WriteLine(string)
+ IL_000b: nop
+ IL_000c: ldc.i4.5
+ IL_000d: stsfld int32 A::i
+ IL_0012: newobj instance void [mscorlib]System.Exception::.ctor()
+ IL_0017: throw
+ } // end of method A::.cctor
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method A::.ctor
+
+} // end of class A
+
+.class public sequential ansi sealed B
+ extends [mscorlib]System.ValueType
+{
+ .pack 0
+ .size 1
+ .field public static int32 i
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ // Code size 24 (0x18)
+ .maxstack 8
+ IL_0000: nop
+ IL_0001: ldstr "In B.cctor"
+ IL_0006: call void [System.Console]System.Console::WriteLine(string)
+ IL_000b: nop
+ IL_000c: ldc.i4.5
+ IL_000d: stsfld int32 B::i
+ IL_0012: newobj instance void [mscorlib]System.Exception::.ctor()
+ IL_0017: throw
+ } // end of method B::.cctor
+
+} // end of class B
+
+.class public auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 405 (0x195)
+ .maxstack 2
+ .locals init (bool V_0,
+ class [mscorlib]System.Exception V_1,
+ int32 V_2,
+ bool V_3)
+ IL_0000: nop
+ IL_0001: ldc.i4.1
+ IL_0002: stloc.0
+ .try
+ {
+ IL_0003: nop
+ IL_0004: ldstr "Accessing class's static field"
+ IL_0009: call void [System.Console]System.Console::WriteLine(string)
+ IL_000e: nop
+ IL_000f: ldstr "A.i: "
+ IL_0014: ldsfld int32 A::i
+ IL_0019: box [mscorlib]System.Int32
+ IL_001e: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0023: call void [System.Console]System.Console::WriteLine(string)
+ IL_0028: nop
+ IL_0029: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_002e: call void [System.Console]System.Console::WriteLine(string)
+ IL_0033: nop
+ IL_0034: ldc.i4.0
+ IL_0035: stloc.0
+ IL_0036: nop
+ IL_0037: leave.s IL_0061
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_0039: pop
+ IL_003a: nop
+ IL_003b: ldstr "Caught expected exception 1st time"
+ IL_0040: call void [System.Console]System.Console::WriteLine(string)
+ IL_0045: nop
+ IL_0046: nop
+ IL_0047: leave.s IL_0061
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_0049: stloc.1
+ IL_004a: nop
+ IL_004b: ldstr "Caught unexpected exception: "
+ IL_0050: ldloc.1
+ IL_0051: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0056: call void [System.Console]System.Console::WriteLine(string)
+ IL_005b: nop
+ IL_005c: ldc.i4.0
+ IL_005d: stloc.0
+ IL_005e: nop
+ IL_005f: leave.s IL_0061
+
+ } // end handler
+ IL_0061: nop
+ .try
+ {
+ IL_0062: nop
+ IL_0063: ldstr "A.i: "
+ IL_0068: ldsfld int32 A::i
+ IL_006d: box [mscorlib]System.Int32
+ IL_0072: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0077: call void [System.Console]System.Console::WriteLine(string)
+ IL_007c: nop
+ IL_007d: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_0082: call void [System.Console]System.Console::WriteLine(string)
+ IL_0087: nop
+ IL_0088: ldc.i4.0
+ IL_0089: stloc.0
+ IL_008a: nop
+ IL_008b: leave.s IL_00b5
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_008d: pop
+ IL_008e: nop
+ IL_008f: ldstr "Caught expected exception 2nd time\n"
+ IL_0094: call void [System.Console]System.Console::WriteLine(string)
+ IL_0099: nop
+ IL_009a: nop
+ IL_009b: leave.s IL_00b5
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_009d: stloc.1
+ IL_009e: nop
+ IL_009f: ldstr "Caught unexpected exception: "
+ IL_00a4: ldloc.1
+ IL_00a5: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_00aa: call void [System.Console]System.Console::WriteLine(string)
+ IL_00af: nop
+ IL_00b0: ldc.i4.0
+ IL_00b1: stloc.0
+ IL_00b2: nop
+ IL_00b3: leave.s IL_00b5
+
+ } // end handler
+ IL_00b5: nop
+ IL_00b6: ldstr "Accessing struct's static field"
+ IL_00bb: call void [System.Console]System.Console::WriteLine(string)
+ IL_00c0: nop
+ .try
+ {
+ IL_00c1: nop
+ IL_00c2: ldstr "B.i: "
+ IL_00c7: ldsfld int32 B::i
+ IL_00cc: box [mscorlib]System.Int32
+ IL_00d1: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_00d6: call void [System.Console]System.Console::WriteLine(string)
+ IL_00db: nop
+ IL_00dc: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_00e1: call void [System.Console]System.Console::WriteLine(string)
+ IL_00e6: nop
+ IL_00e7: ldc.i4.0
+ IL_00e8: stloc.0
+ IL_00e9: nop
+ IL_00ea: leave.s IL_0114
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_00ec: pop
+ IL_00ed: nop
+ IL_00ee: ldstr "Caught expected exception 1st time"
+ IL_00f3: call void [System.Console]System.Console::WriteLine(string)
+ IL_00f8: nop
+ IL_00f9: nop
+ IL_00fa: leave.s IL_0114
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_00fc: stloc.1
+ IL_00fd: nop
+ IL_00fe: ldstr "Caught unexpected exception: "
+ IL_0103: ldloc.1
+ IL_0104: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_0109: call void [System.Console]System.Console::WriteLine(string)
+ IL_010e: nop
+ IL_010f: ldc.i4.0
+ IL_0110: stloc.0
+ IL_0111: nop
+ IL_0112: leave.s IL_0114
+
+ } // end handler
+ IL_0114: nop
+ .try
+ {
+ IL_0115: nop
+ IL_0116: ldstr "B.i: "
+ IL_011b: ldsfld int32 B::i
+ IL_0120: box [mscorlib]System.Int32
+ IL_0125: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_012a: call void [System.Console]System.Console::WriteLine(string)
+ IL_012f: nop
+ IL_0130: ldstr "Did not catch expected TypeInitializationException"
+ + " exception"
+ IL_0135: call void [System.Console]System.Console::WriteLine(string)
+ IL_013a: nop
+ IL_013b: ldc.i4.0
+ IL_013c: stloc.0
+ IL_013d: nop
+ IL_013e: leave.s IL_0168
+
+ } // end .try
+ catch [mscorlib]System.TypeInitializationException
+ {
+ IL_0140: pop
+ IL_0141: nop
+ IL_0142: ldstr "Caught expected exception 2nd time\n"
+ IL_0147: call void [System.Console]System.Console::WriteLine(string)
+ IL_014c: nop
+ IL_014d: nop
+ IL_014e: leave.s IL_0168
+
+ } // end handler
+ catch [mscorlib]System.Exception
+ {
+ IL_0150: stloc.1
+ IL_0151: nop
+ IL_0152: ldstr "Caught unexpected exception: "
+ IL_0157: ldloc.1
+ IL_0158: call string [mscorlib]System.String::Concat(object,
+ object)
+ IL_015d: call void [System.Console]System.Console::WriteLine(string)
+ IL_0162: nop
+ IL_0163: ldc.i4.0
+ IL_0164: stloc.0
+ IL_0165: nop
+ IL_0166: leave.s IL_0168
+
+ } // end handler
+ IL_0168: nop
+ IL_0169: ldloc.0
+ IL_016a: ldc.i4.0
+ IL_016b: ceq
+ IL_016d: stloc.3
+ IL_016e: ldloc.3
+ IL_016f: brtrue.s IL_0182
+
+ IL_0171: nop
+ IL_0172: ldstr "PASS"
+ IL_0177: call void [System.Console]System.Console::WriteLine(string)
+ IL_017c: nop
+ IL_017d: ldc.i4.s 100
+ IL_017f: stloc.2
+ IL_0180: br.s IL_0193
+
+ IL_0182: nop
+ IL_0183: ldstr "FAIL"
+ IL_0188: call void [System.Console]System.Console::WriteLine(string)
+ IL_018d: nop
+ IL_018e: ldc.i4.s 101
+ IL_0190: stloc.2
+ IL_0191: br.s IL_0193
+
+ IL_0193: ldloc.2
+ IL_0194: ret
+ } // end of method Test::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: ret
+ } // end of method Test::.ctor
+
+} // end of class Test
+
+
+// =============================================================
+
+// *********** DISASSEMBLY COMPLETE ***********************
+// WARNING: Created Win32 resource file TypeLoadInitExcepBFI.res
diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.ilproj b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.ilproj
new file mode 100644
index 0000000000..a4da803e17
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CctorThrowStaticFieldBFI.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorThrowStaticFieldBFI</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorThrowStaticFieldBFI.il" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.cs b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.cs
new file mode 100644
index 0000000000..5b6b090709
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.cs
@@ -0,0 +1,180 @@
+// 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.
+
+/*
+A --> B --> C --> D --> E --> A
+3 threads: Thread T1 starts initialization at A, thread T2 starts initialization at C, and thread T3 starts initialization at E.
+A::.cctor sleeps for a few seconds so Thread T1 is blocked.
+C::.cctor sleeps for a few seconds so Thread T2 is blocked.
+
+T3 invokes E::.cctor and blocks because T1 is in A::.cctor.
+T1 becomes unblocked, invokes B::.cctor, tries to invoke C::.cctor and becomes blocked (because C::.cctor is used by T2).
+T2 becomes unblocked , invokes D.::cctor, tries to invokes E::.cctor at which point we get 3 thread deadlock since T3 is waiting for T1 and T1 is waiting for T2 and T2 is waiting for T3.
+We detect the deadlock and allow T2 to see E.i uninitialized state.
+
+In D.cctor: thread T2: E.i 0
+In C.cctor: thread T2: D.i 8
+In B.cctor: thread T1: C.i 7
+In A.cctor: thread T1: B.i 6
+In E.cctor: thread T3: A.i 5
+*/
+
+using System;
+using System.Threading;
+using System.Runtime.CompilerServices;
+public class A
+{
+ public static int i;
+
+ static A()
+ {
+
+ Thread.Sleep(1000*2); // 1 second
+ Console.WriteLine("In A.cctor: thread {0}: B.i {1}",Thread.CurrentThread.Name,B.i);
+ A.i = 5;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class B
+{
+ public static int i;
+
+ static B()
+ {
+
+
+ Console.WriteLine("In B.cctor: thread {0}: C.i {1}",Thread.CurrentThread.Name,C.i);
+ B.i = 6;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class C
+{
+ public static int i;
+
+ static C()
+ {
+
+ Thread.Sleep(1000*2); // 1 second
+ Console.WriteLine("In C.cctor: thread {0}: D.i {1}",Thread.CurrentThread.Name,D.i);
+ C.i = 7;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class D
+{
+ public static int i;
+
+ static D()
+ {
+ Console.WriteLine("In D.cctor: thread {0}: E.i {1}",Thread.CurrentThread.Name,E.i);
+ D.i = 8;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class E
+{
+ public static int i;
+
+ static E()
+ {
+ Console.WriteLine("In E.cctor: thread {0}: A.i {1}",Thread.CurrentThread.Name,A.i);
+ E.i = 9;
+ }
+
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod()
+ {
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+
+}
+
+public class Test
+{
+
+ public static void RunGetA()
+ {
+ A.SomeMethod();
+ }
+
+ public static void RunGetC()
+ {
+ C.SomeMethod();
+ }
+
+ public static void RunGetE()
+ {
+ E.SomeMethod();
+ }
+
+
+ public static int Main()
+ {
+
+ Thread t1 = new Thread(RunGetA);
+ t1.Name = "T1";
+ Thread t2 = new Thread(RunGetC);
+ t2.Name = "T2";
+ Thread t3 = new Thread(RunGetE);
+ t3.Name = "T3";
+
+
+
+ t1.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t2.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t3.Start();
+
+ t3.Join();
+ t2.Join();
+ t1.Join();
+
+ // make sure that statics were set correctly.
+ if ( A.i == 5 && B.i == 6 && C.i == 7 && D.i == 8 && E.i == 9 )
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.csproj b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.csproj
new file mode 100644
index 0000000000..d6d7447389
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/CircularCctorThreeThreads03.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CircularCctorThreeThreads03</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CircularCctorThreeThreads03.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/app.config b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/app.config
new file mode 100644
index 0000000000..e5622f77ad
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/app.config
@@ -0,0 +1,27 @@
+<?xml version = "1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/tests/src/Loader/classloader/TypeInitialization/CoreCLR/project.json b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/project.json
new file mode 100644
index 0000000000..a2e84dc340
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/CoreCLR/project.json
@@ -0,0 +1,35 @@
+{
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816",
+ "System.Collections": "4.0.10",
+ "System.Collections.NonGeneric": "4.0.1-rc2-23816",
+ "System.Collections.Specialized": "4.0.1-rc2-23816",
+ "System.ComponentModel": "4.0.1-rc2-23816",
+ "System.Console": "4.0.0-rc2-23816",
+ "System.Diagnostics.Process": "4.1.0-rc2-23816",
+ "System.Globalization": "4.0.10",
+ "System.Globalization.Calendars": "4.0.0",
+ "System.IO": "4.0.10",
+ "System.IO.FileSystem": "4.0.0",
+ "System.IO.FileSystem.Primitives": "4.0.0",
+ "System.Linq": "4.0.1-rc2-23816",
+ "System.Linq.Queryable": "4.0.1-rc2-23816",
+ "System.Reflection": "4.0.10",
+ "System.Reflection.Primitives": "4.0.0",
+ "System.Runtime": "4.1.0-rc2-23816",
+ "System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.Handles": "4.0.0",
+ "System.Runtime.InteropServices": "4.1.0-rc2-23816",
+ "System.Runtime.Loader": "4.0.0-rc2-23816",
+ "System.Text.Encoding": "4.0.10",
+ "System.Threading": "4.0.10",
+ "System.Threading.Thread": "4.0.0-rc2-23816",
+ "System.Xml.ReaderWriter": "4.0.11-rc2-23816",
+ "System.Xml.XDocument": "4.0.11-rc2-23816",
+ "System.Xml.XmlDocument": "4.0.1-rc2-23816",
+ "System.Xml.XmlSerializer": "4.0.11-rc2-23816"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.cs
new file mode 100644
index 0000000000..77fa7ba329
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.cs
@@ -0,0 +1,127 @@
+// 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.
+
+// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn
+// is invoked.
+
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+public class Foo
+{
+ public static void Meth_In()
+ {
+ // NotInlined.NotInlinedMeth is not inlined
+ NotInlined.NotInlinedMeth<int>();
+ }
+
+ public static void Meth_NotIn()
+ {
+ // Inlined.InlinedMeth is inlined
+ Inlined.InlinedMeth<Foo>();
+ }
+
+ public static void ValMeth_In()
+ {
+ // NotInlinedVal.NotInlinedValMeth is not inlined
+ NotInlinedVal.NotInlinedValMeth<char>();
+ }
+
+ public static void ValMeth_NotIn()
+ {
+ // InlinedVal.InlinedValMeth is inlined
+ InlinedVal.InlinedValMeth<NotInlined>();
+ }
+}
+
+public class NotInlined
+{
+
+ static NotInlined()
+ {
+ Console.WriteLine("Inside NotInlined::.cctor");
+ File.WriteAllText("notinlined.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedMeth<T>()
+ {
+ }
+}
+
+
+public class Inlined
+{
+
+ static Inlined()
+ {
+ Console.WriteLine("Inside Inlined::.cctor");
+ File.WriteAllText("inlined.txt", "inside .cctor");
+ }
+
+ public static void InlinedMeth<T>()
+ {
+ }
+}
+
+
+public struct NotInlinedVal
+{
+
+ static NotInlinedVal()
+ {
+ Console.WriteLine("Inside NotInlinedVal::.cctor");
+ File.WriteAllText("notinlinedval.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedValMeth<T>()
+ {
+ }
+}
+
+
+public struct InlinedVal
+{
+
+ static InlinedVal()
+ {
+ Console.WriteLine("Inside InlinedVal::.cctor");
+ File.WriteAllText("inlinedval.txt", "inside .cctor");
+ }
+
+ public static void InlinedValMeth<T>()
+ {
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+ Foo.Meth_In();
+ Foo.Meth_NotIn();
+
+ Foo.ValMeth_In();
+ Foo.ValMeth_NotIn();
+
+ if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") )
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ File.Delete("inlined.txt");
+ File.Delete("notinlined.txt");
+ File.Delete("inlinedval.txt");
+ File.Delete("notinlinedval.txt");
+ return 100;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.csproj
new file mode 100644
index 0000000000..5c46374fdd
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>GenMethInlined</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="GenMethInlined.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.cs
new file mode 100644
index 0000000000..0eab4443b1
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.cs
@@ -0,0 +1,155 @@
+// 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.
+
+// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn
+// is invoked in multinested scenario.
+
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+public class Bar
+{
+ public static void BarMeth_In()
+ {
+ Foo.Meth_In();
+ }
+
+ public static void BarMeth_NotIn()
+ {
+ Foo.Meth_NotIn();
+ }
+
+ public static void BarValMeth_In()
+ {
+ Foo.ValMeth_In();
+ }
+
+ public static void BarValMeth_NotIn()
+ {
+ Foo.ValMeth_NotIn();
+ }
+
+}
+
+
+
+public class Foo
+{
+ public static void Meth_In()
+ {
+ // NotInlined.NotInlinedMeth is not inlined
+ NotInlined.NotInlinedMeth<int>();
+ }
+
+ public static void Meth_NotIn()
+ {
+ // Inlined.InlinedMeth is inlined
+ Inlined.InlinedMeth<char>();
+ }
+
+ public static void ValMeth_In()
+ {
+ // NotInlinedVal.NotInlinedValMeth is not inlined
+ NotInlinedVal.NotInlinedValMeth<String>();
+ }
+
+ public static void ValMeth_NotIn()
+ {
+ // InlinedVal.InlinedValMeth is inlined
+ InlinedVal.InlinedValMeth<Bar>();
+ }
+}
+
+
+
+public class NotInlined
+{
+
+ static NotInlined()
+ {
+ Console.WriteLine("Inside NotInlined::.cctor");
+ File.WriteAllText("notinlined.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedMeth<T>()
+ {
+ }
+}
+
+
+public class Inlined
+{
+
+ static Inlined()
+ {
+ Console.WriteLine("Inside Inlined::.cctor");
+ File.WriteAllText("inlined.txt", "inside .cctor");
+ }
+
+ public static void InlinedMeth<T>()
+ {
+ }
+}
+
+
+public struct NotInlinedVal
+{
+
+ static NotInlinedVal()
+ {
+ Console.WriteLine("Inside NotInlinedVal::.cctor");
+ File.WriteAllText("notinlinedval.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedValMeth<T>()
+ {
+ }
+}
+
+
+public struct InlinedVal
+{
+
+ static InlinedVal()
+ {
+ Console.WriteLine("Inside InlinedVal::.cctor");
+ File.WriteAllText("inlinedval.txt", "inside .cctor");
+ }
+
+ public static void InlinedValMeth<T>()
+ {
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+ Bar.BarMeth_In();
+ Bar.BarMeth_NotIn();
+
+ Bar.BarValMeth_In();
+ Bar.BarValMeth_NotIn();
+
+ if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") )
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ File.Delete("inlined.txt");
+ File.Delete("notinlined.txt");
+ File.Delete("inlinedval.txt");
+ File.Delete("notinlinedval.txt");
+ return 100;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.csproj
new file mode 100644
index 0000000000..c5415946b2
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenMethInlined_Multinested.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>GenMethInlined_Multinested</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="GenMethInlined_Multinested.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.cs
new file mode 100644
index 0000000000..6709f344a6
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.cs
@@ -0,0 +1,126 @@
+// 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.
+
+// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn is invoked.
+
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+public class Foo<T>
+{
+ public static void Meth_In()
+ {
+ // NotInlined.NotInlinedMeth is not inlined
+ NotInlined<int>.NotInlinedMeth();
+ }
+
+ public static void Meth_NotIn()
+ {
+ // Inlined.InlinedMeth is inlined
+ Inlined<int>.InlinedMeth();
+ }
+
+ public static void ValMeth_In()
+ {
+ // NotInlinedVal.NotInlinedValMeth is not inlined
+ NotInlinedVal<int>.NotInlinedValMeth();
+ }
+
+ public static void ValMeth_NotIn()
+ {
+ // InlinedVal.InlinedValMeth is inlined
+ InlinedVal<int>.InlinedValMeth();
+ }
+}
+
+public class NotInlined<T>
+{
+
+ static NotInlined()
+ {
+ Console.WriteLine("Inside NotInlined::.cctor");
+ File.WriteAllText("notinlined.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedMeth()
+ {
+ }
+}
+
+
+public class Inlined<T>
+{
+
+ static Inlined()
+ {
+ Console.WriteLine("Inside Inlined::.cctor");
+ File.WriteAllText("inlined.txt", "inside .cctor");
+ }
+
+ public static void InlinedMeth()
+ {
+ }
+}
+
+
+public struct NotInlinedVal<T>
+{
+
+ static NotInlinedVal()
+ {
+ Console.WriteLine("Inside NotInlinedVal::.cctor");
+ File.WriteAllText("notinlinedval.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedValMeth()
+ {
+ }
+}
+
+
+public struct InlinedVal<T>
+{
+
+ static InlinedVal()
+ {
+ Console.WriteLine("Inside InlinedVal::.cctor");
+ File.WriteAllText("inlinedval.txt", "inside .cctor");
+ }
+
+ public static void InlinedValMeth()
+ {
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+ Foo<int>.Meth_In();
+ Foo<char>.Meth_NotIn();
+
+ Foo<InlinedVal<int>>.ValMeth_In();
+ Foo<NotInlined<bool>>.ValMeth_NotIn();
+
+ if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") )
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ File.Delete("inlined.txt");
+ File.Delete("notinlined.txt");
+ File.Delete("inlinedval.txt");
+ File.Delete("notinlinedval.txt");
+ return 100;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.csproj
new file mode 100644
index 0000000000..0314a84eb3
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>GenTypeInlined</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="GenTypeInlined.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.cs
new file mode 100644
index 0000000000..6cbed4ca75
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.cs
@@ -0,0 +1,154 @@
+// 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.
+
+// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn
+// is invoked in multinested scenario.
+
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+public class Bar<T>
+{
+ public static void BarMeth_In()
+ {
+ Foo<int>.Meth_In();
+ }
+
+ public static void BarMeth_NotIn()
+ {
+ Foo<Foo<int>>.Meth_NotIn();
+ }
+
+ public static void BarValMeth_In()
+ {
+ Foo<char>.ValMeth_In();
+ }
+
+ public static void BarValMeth_NotIn()
+ {
+ Foo<Bar<String>>.ValMeth_NotIn();
+ }
+}
+
+
+
+public class Foo<U>
+{
+ public static void Meth_In()
+ {
+ // NotInlined.NotInlinedMeth is not inlined
+ NotInlined<int>.NotInlinedMeth();
+ }
+
+ public static void Meth_NotIn()
+ {
+ // Inlined.InlinedMeth is inlined
+ Inlined<int>.InlinedMeth();
+ }
+
+ public static void ValMeth_In()
+ {
+ // NotInlinedVal.NotInlinedValMeth is not inlined
+ NotInlinedVal<int>.NotInlinedValMeth();
+ }
+
+ public static void ValMeth_NotIn()
+ {
+ // InlinedVal.InlinedValMeth is inlined
+ InlinedVal<int>.InlinedValMeth();
+ }
+}
+
+
+
+public class NotInlined<T>
+{
+
+ static NotInlined()
+ {
+ Console.WriteLine("Inside NotInlined::.cctor");
+ File.WriteAllText("notinlined.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedMeth()
+ {
+ }
+}
+
+
+public class Inlined<T>
+{
+
+ static Inlined()
+ {
+ Console.WriteLine("Inside Inlined::.cctor");
+ File.WriteAllText("inlined.txt", "inside .cctor");
+ }
+
+ public static void InlinedMeth()
+ {
+ }
+}
+
+
+public struct NotInlinedVal<T>
+{
+
+ static NotInlinedVal()
+ {
+ Console.WriteLine("Inside NotInlinedVal::.cctor");
+ File.WriteAllText("notinlinedval.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedValMeth()
+ {
+ }
+}
+
+
+public struct InlinedVal<T>
+{
+
+ static InlinedVal()
+ {
+ Console.WriteLine("Inside InlinedVal::.cctor");
+ File.WriteAllText("inlinedval.txt", "inside .cctor");
+ }
+
+ public static void InlinedValMeth()
+ {
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+ Foo<int>.Meth_In();
+
+ Bar<int>.BarMeth_NotIn();
+
+ Bar<int>.BarValMeth_In();
+ Bar<int>.BarValMeth_NotIn();
+
+ if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") )
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ File.Delete("inlined.txt");
+ File.Delete("notinlined.txt");
+ File.Delete("inlinedval.txt");
+ File.Delete("notinlinedval.txt");
+ return 100;
+ }
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.csproj
new file mode 100644
index 0000000000..e776b199af
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/GenTypeInlined_Multinested.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>GenTypeInlined_Multinested</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="GenTypeInlined_Multinested.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.cs
new file mode 100644
index 0000000000..f73dd52fc7
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.cs
@@ -0,0 +1,126 @@
+// 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.
+
+// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn is invoked.
+
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+public class Foo
+{
+ public static void Meth_In()
+ {
+ // NotInlined.NotInlinedMeth is not inlined
+ NotInlined.NotInlinedMeth();
+ }
+
+ public static void Meth_NotIn()
+ {
+ // Inlined.InlinedMeth is inlined
+ Inlined.InlinedMeth();
+ }
+
+ public static void ValMeth_In()
+ {
+ // NotInlinedVal.NotInlinedValMeth is not inlined
+ NotInlinedVal.NotInlinedValMeth();
+ }
+
+ public static void ValMeth_NotIn()
+ {
+ // InlinedVal.InlinedValMeth is inlined
+ InlinedVal.InlinedValMeth();
+ }
+}
+
+public class NotInlined
+{
+
+ static NotInlined()
+ {
+ Console.WriteLine("Inside NotInlined::.cctor");
+ File.WriteAllText("notinlined.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedMeth()
+ {
+ }
+}
+
+
+public class Inlined
+{
+
+ static Inlined()
+ {
+ Console.WriteLine("Inside Inlined::.cctor");
+ File.WriteAllText("inlined.txt", "inside .cctor");
+ }
+
+ public static void InlinedMeth()
+ {
+ }
+}
+
+
+public struct NotInlinedVal
+{
+
+ static NotInlinedVal()
+ {
+ Console.WriteLine("Inside NotInlinedVal::.cctor");
+ File.WriteAllText("notinlinedval.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedValMeth()
+ {
+ }
+}
+
+
+public struct InlinedVal
+{
+
+ static InlinedVal()
+ {
+ Console.WriteLine("Inside InlinedVal::.cctor");
+ File.WriteAllText("inlinedval.txt", "inside .cctor");
+ }
+
+ public static void InlinedValMeth()
+ {
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+ Foo.Meth_In();
+ Foo.Meth_NotIn();
+
+ Foo.ValMeth_In();
+ Foo.ValMeth_NotIn();
+
+ if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") )
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ File.Delete("inlined.txt");
+ File.Delete("notinlined.txt");
+ File.Delete("inlinedval.txt");
+ File.Delete("notinlinedval.txt");
+ return 100;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.csproj
new file mode 100644
index 0000000000..46d088b382
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>Inlined</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="Inlined.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.cs b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.cs
new file mode 100644
index 0000000000..a09d865546
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.cs
@@ -0,0 +1,154 @@
+// 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.
+
+// test that .cctor of NotInlined and Inlined (class/struct) is called when Foo.Meth_In and Foo_Meth_NotIn is invoked.
+
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+
+public class Bar
+{
+ public static void BarMeth_In()
+ {
+ Foo.Meth_In();
+ }
+
+ public static void BarMeth_NotIn()
+ {
+ Foo.Meth_NotIn();
+ }
+
+ public static void BarValMeth_In()
+ {
+ Foo.ValMeth_In();
+ }
+
+ public static void BarValMeth_NotIn()
+ {
+ Foo.ValMeth_NotIn();
+ }
+
+}
+
+
+
+public class Foo
+{
+ public static void Meth_In()
+ {
+ // NotInlined.NotInlinedMeth is not inlined
+ NotInlined.NotInlinedMeth();
+ }
+
+ public static void Meth_NotIn()
+ {
+ // Inlined.InlinedMeth is inlined
+ Inlined.InlinedMeth();
+ }
+
+ public static void ValMeth_In()
+ {
+ // NotInlinedVal.NotInlinedValMeth is not inlined
+ NotInlinedVal.NotInlinedValMeth();
+ }
+
+ public static void ValMeth_NotIn()
+ {
+ // InlinedVal.InlinedValMeth is inlined
+ InlinedVal.InlinedValMeth();
+ }
+}
+
+
+
+public class NotInlined
+{
+
+ static NotInlined()
+ {
+ Console.WriteLine("Inside NotInlined::.cctor");
+ File.WriteAllText("notinlined.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedMeth()
+ {
+ }
+}
+
+
+public class Inlined
+{
+
+ static Inlined()
+ {
+ Console.WriteLine("Inside Inlined::.cctor");
+ File.WriteAllText("inlined.txt", "inside .cctor");
+ }
+
+ public static void InlinedMeth()
+ {
+ }
+}
+
+
+public struct NotInlinedVal
+{
+
+ static NotInlinedVal()
+ {
+ Console.WriteLine("Inside NotInlinedVal::.cctor");
+ File.WriteAllText("notinlinedval.txt", "inside .cctor");
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void NotInlinedValMeth()
+ {
+ }
+}
+
+
+public struct InlinedVal
+{
+
+ static InlinedVal()
+ {
+ Console.WriteLine("Inside InlinedVal::.cctor");
+ File.WriteAllText("inlinedval.txt", "inside .cctor");
+ }
+
+ public static void InlinedValMeth()
+ {
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+ Bar.BarMeth_In();
+ Bar.BarMeth_NotIn();
+
+ Bar.BarValMeth_In();
+ Bar.BarValMeth_NotIn();
+
+ if (!File.Exists("inlined.txt") || !File.Exists("notinlined.txt") || !File.Exists("inlinedval.txt") || !File.Exists("notinlinedval.txt") )
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ File.Delete("inlined.txt");
+ File.Delete("notinlined.txt");
+ File.Delete("inlinedval.txt");
+ File.Delete("notinlinedval.txt");
+ return 100;
+ }
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.csproj b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.csproj
new file mode 100644
index 0000000000..77bb024bff
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/Inlined_Multinested.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>Inlined_Multinested</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="Inlined_Multinested.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/app.config b/tests/src/Loader/classloader/TypeInitialization/Inlining/app.config
new file mode 100644
index 0000000000..e5622f77ad
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/app.config
@@ -0,0 +1,27 @@
+<?xml version = "1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/tests/src/Loader/classloader/TypeInitialization/Inlining/project.json b/tests/src/Loader/classloader/TypeInitialization/Inlining/project.json
new file mode 100644
index 0000000000..a2e84dc340
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/Inlining/project.json
@@ -0,0 +1,35 @@
+{
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816",
+ "System.Collections": "4.0.10",
+ "System.Collections.NonGeneric": "4.0.1-rc2-23816",
+ "System.Collections.Specialized": "4.0.1-rc2-23816",
+ "System.ComponentModel": "4.0.1-rc2-23816",
+ "System.Console": "4.0.0-rc2-23816",
+ "System.Diagnostics.Process": "4.1.0-rc2-23816",
+ "System.Globalization": "4.0.10",
+ "System.Globalization.Calendars": "4.0.0",
+ "System.IO": "4.0.10",
+ "System.IO.FileSystem": "4.0.0",
+ "System.IO.FileSystem.Primitives": "4.0.0",
+ "System.Linq": "4.0.1-rc2-23816",
+ "System.Linq.Queryable": "4.0.1-rc2-23816",
+ "System.Reflection": "4.0.10",
+ "System.Reflection.Primitives": "4.0.0",
+ "System.Runtime": "4.1.0-rc2-23816",
+ "System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.Handles": "4.0.0",
+ "System.Runtime.InteropServices": "4.1.0-rc2-23816",
+ "System.Runtime.Loader": "4.0.0-rc2-23816",
+ "System.Text.Encoding": "4.0.10",
+ "System.Threading": "4.0.10",
+ "System.Threading.Thread": "4.0.0-rc2-23816",
+ "System.Xml.ReaderWriter": "4.0.11-rc2-23816",
+ "System.Xml.XDocument": "4.0.11-rc2-23816",
+ "System.Xml.XmlDocument": "4.0.1-rc2-23816",
+ "System.Xml.XmlSerializer": "4.0.11-rc2-23816"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.cs b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.cs
new file mode 100644
index 0000000000..7279d6c274
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.cs
@@ -0,0 +1,70 @@
+// 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.
+
+// Call a non-virtual instance method of a zero-constructed value type
+// The method doesn't access type's static fields.
+
+using System;
+using System.IO;
+
+public class FLAG
+{
+ public static bool success = false;
+}
+
+
+public struct A
+{
+ public static int i;
+
+ static A()
+ {
+
+ Console.WriteLine("In A.cctor");
+ FLAG.success = true;
+ }
+
+ public void methodA()
+ {
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+
+ Console.WriteLine("\n============================================================");
+ Console.WriteLine("NOTE: This test will fail with NGEN");
+ Console.WriteLine("We do not guarantee to execute static .cctor for structs");
+ Console.WriteLine("unless the instance .ctor is explicitly called\n");
+ Console.WriteLine("============================================================");
+
+ try
+ {
+ // this will trigger A::.cctor
+ A a = new A();
+
+ a.methodA();
+
+ if(!FLAG.success)
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ return 100;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("FAIL: Caught unexpected exception: " + e);
+ return 102;
+ }
+ }
+}
+
diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.csproj b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.csproj
new file mode 100644
index 0000000000..0857ef3dfc
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal01.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorZeroVal01</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorZeroVal01.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.cs b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.cs
new file mode 100644
index 0000000000..8f3ded3cca
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.cs
@@ -0,0 +1,64 @@
+// 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.
+
+// Call a non-virtual instance method of a zero-constructed value type
+// The method accesses type's static fields.
+
+using System;
+using System.IO;
+
+public class FLAG
+{
+ public static bool success = false;
+}
+
+
+public struct A
+{
+ public static int i;
+
+ static A()
+ {
+
+ Console.WriteLine("In A.cctor");
+ FLAG.success = true;
+ }
+
+ public void methodA()
+ {
+ A.i = 5;
+ //Console.WriteLine("A.i : " + i);
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+
+ try
+ {
+ A a = new A();
+
+ a.methodA();
+
+ if (!FLAG.success)
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ return 100;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("FAIL: Caught unexpected exception: " + e);
+ return 102;
+ }
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.csproj b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.csproj
new file mode 100644
index 0000000000..3a7bf57366
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal02.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorZeroVal02</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorZeroVal02.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.cs b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.cs
new file mode 100644
index 0000000000..ca7c80b0e9
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.cs
@@ -0,0 +1,65 @@
+// 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.
+
+// Call a non-virtual instance method of a zero-constructed value type
+// The method accesses type's instance fields.
+
+using System;
+using System.IO;
+
+public class FLAG
+{
+ public static bool success = false;
+}
+
+
+public struct A
+{
+ public static int i;
+
+ static A()
+ {
+ Console.WriteLine("In A.cctor");
+ FLAG.success = true;
+ }
+
+ public void methodA()
+ {
+ i = 5;
+
+ }
+}
+
+
+public class Test
+{
+ public static int Main()
+ {
+
+ try
+ {
+ A a = new A();
+
+ a.methodA();
+
+ if (!FLAG.success)
+ {
+ Console.WriteLine("FAIL: Cctor wasn't called");
+ return 101;
+ }
+ else
+ {
+ Console.WriteLine("PASS: Cctor was called");
+ return 100;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("FAIL: Caught unexpected exception: " + e);
+ return 102;
+ }
+
+
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.csproj b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.csproj
new file mode 100644
index 0000000000..0e3f6de18a
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/CctorZeroVal03.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>CctorZeroVal03</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="CctorZeroVal03.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/app.config b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/app.config
new file mode 100644
index 0000000000..e5622f77ad
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/app.config
@@ -0,0 +1,27 @@
+<?xml version = "1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/project.json b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/project.json
new file mode 100644
index 0000000000..a2e84dc340
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/ThisNulllPointer/project.json
@@ -0,0 +1,35 @@
+{
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816",
+ "System.Collections": "4.0.10",
+ "System.Collections.NonGeneric": "4.0.1-rc2-23816",
+ "System.Collections.Specialized": "4.0.1-rc2-23816",
+ "System.ComponentModel": "4.0.1-rc2-23816",
+ "System.Console": "4.0.0-rc2-23816",
+ "System.Diagnostics.Process": "4.1.0-rc2-23816",
+ "System.Globalization": "4.0.10",
+ "System.Globalization.Calendars": "4.0.0",
+ "System.IO": "4.0.10",
+ "System.IO.FileSystem": "4.0.0",
+ "System.IO.FileSystem.Primitives": "4.0.0",
+ "System.Linq": "4.0.1-rc2-23816",
+ "System.Linq.Queryable": "4.0.1-rc2-23816",
+ "System.Reflection": "4.0.10",
+ "System.Reflection.Primitives": "4.0.0",
+ "System.Runtime": "4.1.0-rc2-23816",
+ "System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.Handles": "4.0.0",
+ "System.Runtime.InteropServices": "4.1.0-rc2-23816",
+ "System.Runtime.Loader": "4.0.0-rc2-23816",
+ "System.Text.Encoding": "4.0.10",
+ "System.Threading": "4.0.10",
+ "System.Threading.Thread": "4.0.0-rc2-23816",
+ "System.Xml.ReaderWriter": "4.0.11-rc2-23816",
+ "System.Xml.XDocument": "4.0.11-rc2-23816",
+ "System.Xml.XmlDocument": "4.0.1-rc2-23816",
+ "System.Xml.XmlSerializer": "4.0.11-rc2-23816"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/backpatching/app.config b/tests/src/Loader/classloader/TypeInitialization/backpatching/app.config
new file mode 100644
index 0000000000..e5622f77ad
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/backpatching/app.config
@@ -0,0 +1,27 @@
+<?xml version = "1.0" encoding="utf-8"?>
+<configuration>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.20.0" newVersion="4.0.20.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Text.Encoding" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Reflection" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/tests/src/Loader/classloader/TypeInitialization/backpatching/project.json b/tests/src/Loader/classloader/TypeInitialization/backpatching/project.json
new file mode 100644
index 0000000000..a2e84dc340
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/backpatching/project.json
@@ -0,0 +1,35 @@
+{
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.0.1-rc2-23816",
+ "System.Collections": "4.0.10",
+ "System.Collections.NonGeneric": "4.0.1-rc2-23816",
+ "System.Collections.Specialized": "4.0.1-rc2-23816",
+ "System.ComponentModel": "4.0.1-rc2-23816",
+ "System.Console": "4.0.0-rc2-23816",
+ "System.Diagnostics.Process": "4.1.0-rc2-23816",
+ "System.Globalization": "4.0.10",
+ "System.Globalization.Calendars": "4.0.0",
+ "System.IO": "4.0.10",
+ "System.IO.FileSystem": "4.0.0",
+ "System.IO.FileSystem.Primitives": "4.0.0",
+ "System.Linq": "4.0.1-rc2-23816",
+ "System.Linq.Queryable": "4.0.1-rc2-23816",
+ "System.Reflection": "4.0.10",
+ "System.Reflection.Primitives": "4.0.0",
+ "System.Runtime": "4.1.0-rc2-23816",
+ "System.Runtime.Extensions": "4.0.10",
+ "System.Runtime.Handles": "4.0.0",
+ "System.Runtime.InteropServices": "4.1.0-rc2-23816",
+ "System.Runtime.Loader": "4.0.0-rc2-23816",
+ "System.Text.Encoding": "4.0.10",
+ "System.Threading": "4.0.10",
+ "System.Threading.Thread": "4.0.0-rc2-23816",
+ "System.Xml.ReaderWriter": "4.0.11-rc2-23816",
+ "System.Xml.XDocument": "4.0.11-rc2-23816",
+ "System.Xml.XmlDocument": "4.0.1-rc2-23816",
+ "System.Xml.XmlSerializer": "4.0.11-rc2-23816"
+ },
+ "frameworks": {
+ "dnxcore50": {}
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.cs b/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.cs
new file mode 100644
index 0000000000..54c199b039
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.cs
@@ -0,0 +1,81 @@
+// 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.Threading;
+using System.Runtime.CompilerServices;
+
+// This test case reproduces a race condition involving type initialization (aka, .cctor, aka static constructor).
+//
+// The idea is that Thread1 initiates a type load and type initialization on MyClass (running of the static constructor/.cctor).
+//
+// While Thread1 is doing this, Thread2 attempts to access a static member, MyClass.X
+// by invoking static method MyClass.getX().
+//
+// The failing behavior is that Thread2 is able to access MyClass.X before it is initialized--Thread1 is still busy
+// with type initialization, but hasn't yet initialized MyClass.X. This is because the prestub for MyClass.getX(), the mechanism that
+// would normally trigger the .cctor to be run, was already run by Thread1. By the time Thread2 hit getX(), there is
+// no more prestub to trigger the .cctor--so Thread2 (effectively) assumes that MyClass is already initialized and
+// proceeds to access the still uninitialized static member, MyClass.X.
+//
+// A likely fix for this would be to delay backpatching getX() until after the .cctor has fully completed.
+// mwilk. 2/3/04.
+
+
+public class MyClass{
+ private static int X;
+ public static int X0;
+ static MyClass(){
+ X0 = getX(); // expect this to return 0, since this forces a cctor loop.
+ Thread.Sleep(1000*5); // 5 seconds
+ X=12;
+ }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int getX(){
+ Console.WriteLine("In MyClass.getX(): thread {0}",Thread.CurrentThread.Name);
+ return X;
+ }
+ // invoking this should trigger the cctor
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void SomeMethod(){
+ Console.WriteLine("In MyClass.SomeMethod(): thread {0}",Thread.CurrentThread.Name);
+ }
+}
+
+public class CMain{
+ public static int X_getX;
+
+ public static void RunSomeMethod(){
+ MyClass.SomeMethod();
+ }
+ public static void RunGetX(){
+
+ X_getX = MyClass.getX();
+ Console.WriteLine("X_getX: {0}: thread {1}",X_getX,Thread.CurrentThread.Name);
+ }
+ public static int Main(){
+ Thread t1 = new Thread(RunSomeMethod);
+ t1.Name = "T1";
+ Thread t2 = new Thread(RunGetX);
+ t2.Name = "T2";
+
+ t1.Start();
+ Thread.Sleep(1000*1); // 1 second
+ t2.Start();
+
+ t2.Join();
+ t1.Join();
+
+
+ //Console.WriteLine("MyClass.X0: {0}",MyClass.X0);
+ if(12==X_getX){
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else{
+ Console.WriteLine("FAIL");
+ return 101;
+ }
+ }
+}
diff --git a/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.csproj b/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.csproj
new file mode 100644
index 0000000000..2319faf07b
--- /dev/null
+++ b/tests/src/Loader/classloader/TypeInitialization/backpatching/test1.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <AssemblyName>test1</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>0</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="test1.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="app.config" />
+ <None Include="project.json" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>