Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 1e1926c

Browse files
committed
Fix for issue 15412
Added an IL test case for this issue Added the template C# simplearg.cs that was used to create the test case simplearg.il Added extra logging around the initial call of impNormStructVal
1 parent c233112 commit 1e1926c

File tree

4 files changed

+265
-4
lines changed

4 files changed

+265
-4
lines changed

src/jit/importer.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,21 @@ GenTreeArgList* Compiler::impPopList(unsigned count, CORINFO_SIG_INFO* sig, GenT
852852
// Morph trees that aren't already OBJs or MKREFANY to be OBJs
853853
assert(ti.IsType(TI_STRUCT));
854854
structType = ti.GetClassHandleForValueClass();
855-
temp = impNormStructVal(temp, structType, (unsigned)CHECK_SPILL_ALL);
855+
#ifdef DEBUG
856+
if (verbose)
857+
{
858+
printf("Calling impNormStructVal on:\n");
859+
gtDispTree(temp);
860+
}
861+
#endif
862+
temp = impNormStructVal(temp, structType, (unsigned)CHECK_SPILL_ALL);
863+
#ifdef DEBUG
864+
if (verbose)
865+
{
866+
printf("resulting tree:\n");
867+
gtDispTree(temp);
868+
}
869+
#endif
856870
}
857871

858872
/* NOTE: we defer bashing the type for I_IMPL to fgMorphArgs */
@@ -1599,7 +1613,7 @@ GenTreePtr Compiler::impNormStructVal(GenTreePtr structVal,
15991613

16001614
case GT_COMMA:
16011615
{
1602-
// The second thing could either be a block node or a GT_SIMD or a GT_COMMA node.
1616+
// The second thing could either be a block node or a GT_FIELD or a GT_SIMD or a GT_COMMA node.
16031617
GenTree* blockNode = structVal->gtOp.gtOp2;
16041618
assert(blockNode->gtType == structType);
16051619

@@ -1616,6 +1630,12 @@ GenTreePtr Compiler::impNormStructVal(GenTreePtr structVal,
16161630
} while (blockNode->OperGet() == GT_COMMA);
16171631
}
16181632

1633+
if (blockNode->OperGet() == GT_FIELD)
1634+
{
1635+
// If we have a GT_FIELD then wrap it in a GT_OBJ.
1636+
blockNode = gtNewObjNode(structHnd, gtNewOperNode(GT_ADDR, TYP_BYREF, blockNode));
1637+
}
1638+
16191639
#ifdef FEATURE_SIMD
16201640
if (blockNode->OperGet() == GT_SIMD)
16211641
{
@@ -1625,7 +1645,7 @@ GenTreePtr Compiler::impNormStructVal(GenTreePtr structVal,
16251645
else
16261646
#endif
16271647
{
1628-
assert(blockNode->OperIsBlk());
1648+
noway_assert(blockNode->OperIsBlk());
16291649

16301650
// Sink the GT_COMMA below the blockNode addr.
16311651
// That is GT_COMMA(op1, op2=blockNode) is tranformed into
@@ -1649,7 +1669,7 @@ GenTreePtr Compiler::impNormStructVal(GenTreePtr structVal,
16491669
break;
16501670

16511671
default:
1652-
assert(!"Unexpected node in impNormStructVal()");
1672+
noway_assert(!"Unexpected node in impNormStructVal()");
16531673
break;
16541674
}
16551675
structVal->gtType = structType;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// This is the template C# code from which the simplearg.il test case is derived
2+
// It was produced by ildasm of the exe produced by this C# program
3+
// The IL is edited to remove beforefieldinit
4+
// and to add an RVA initialization for the field 'Holder.RvaStatic'
5+
6+
using System;
7+
using System.Runtime.CompilerServices;
8+
9+
namespace SimpleArg
10+
{
11+
struct MyValue
12+
{
13+
public int IntValue;
14+
public int PadValue;
15+
public long LongValue;
16+
17+
public MyValue(int init1, long init2) { IntValue = init1; PadValue = 0; LongValue = init2; }
18+
}
19+
20+
class Holder
21+
{
22+
public static MyValue RvaStatic;
23+
public static MyValue NormalStatic = new MyValue(47, 11);
24+
}
25+
26+
class Program
27+
{
28+
[MethodImpl(MethodImplOptions.NoInlining)]
29+
static int Method(MyValue arg)
30+
{
31+
return arg.IntValue;
32+
}
33+
34+
static int Main(string[] args)
35+
{
36+
int result = Method(Holder.RvaStatic);
37+
result += Method(Holder.NormalStatic);
38+
39+
if (result == 100)
40+
{
41+
Console.WriteLine("Passed");
42+
}
43+
else
44+
{
45+
Console.WriteLine("Failed");
46+
Console.WriteLine(result);
47+
}
48+
return result;
49+
}
50+
}
51+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
2+
// Microsoft (R) .NET Framework IL Disassembler. Version 4.7.3071.0
3+
// Copyright (c) Microsoft Corporation. All rights reserved.
4+
5+
// This is a repro case for GitHub issue #15412 ( https://github.com/dotnet/coreclr/issues/15412 )
6+
7+
// Metadata version: v4.0.30319
8+
.assembly extern mscorlib
9+
{
10+
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
11+
.ver 4:0:0:0
12+
}
13+
.assembly repro2
14+
{
15+
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
16+
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
17+
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
18+
.hash algorithm 0x00008004
19+
.ver 0:0:0:0
20+
}
21+
.module repro2.exe
22+
// MVID: {07A1F03C-A750-4BCF-8997-C0AC2CBDB844}
23+
.imagebase 0x00400000
24+
.file alignment 0x00000200
25+
.stackreserve 0x00100000
26+
.subsystem 0x0003 // WINDOWS_CUI
27+
.corflags 0x00000001 // ILONLY
28+
// Image base: 0x000001BBF9F70000
29+
30+
31+
// =============== CLASS MEMBERS DECLARATION ===================
32+
33+
.class private sequential ansi sealed SimpleArg.MyValue
34+
extends [mscorlib]System.ValueType
35+
{
36+
.field public int32 IntValue
37+
.field public int32 PadValue
38+
.field public int64 LongValue
39+
.method public hidebysig specialname rtspecialname
40+
instance void .ctor(int32 init1,
41+
int64 init2) cil managed
42+
{
43+
// Code size 22 (0x16)
44+
.maxstack 8
45+
IL_0000: ldarg.0
46+
IL_0001: ldarg.1
47+
IL_0002: stfld int32 SimpleArg.MyValue::IntValue
48+
IL_0007: ldarg.0
49+
IL_0008: ldc.i4.0
50+
IL_0009: stfld int32 SimpleArg.MyValue::PadValue
51+
IL_000e: ldarg.0
52+
IL_000f: ldarg.2
53+
IL_0010: stfld int64 SimpleArg.MyValue::LongValue
54+
IL_0015: ret
55+
} // end of method MyValue::.ctor
56+
57+
} // end of class SimpleArg.MyValue
58+
59+
.class private auto ansi SimpleArg.Holder
60+
extends [mscorlib]System.Object
61+
{
62+
.field public static valuetype SimpleArg.MyValue RvaStatic at PreInitValue // {31, 0, 12 }
63+
.field public static valuetype SimpleArg.MyValue NormalStatic // {69, 0, 11 }
64+
.method public hidebysig specialname rtspecialname
65+
instance void .ctor() cil managed
66+
{
67+
// Code size 7 (0x7)
68+
.maxstack 8
69+
IL_0000: ldarg.0
70+
IL_0001: call instance void [mscorlib]System.Object::.ctor()
71+
IL_0006: ret
72+
} // end of method Holder::.ctor
73+
74+
.method private hidebysig specialname rtspecialname static
75+
void .cctor() cil managed
76+
{
77+
// Code size 16 (0x10)
78+
.maxstack 8
79+
IL_0000: ldc.i4.s 69
80+
IL_0002: ldc.i4.s 11
81+
IL_0004: conv.i8
82+
IL_0005: newobj instance void SimpleArg.MyValue::.ctor(int32,
83+
int64)
84+
IL_000a: stsfld valuetype SimpleArg.MyValue SimpleArg.Holder::NormalStatic
85+
IL_000f: ret
86+
} // end of method Holder::.cctor
87+
88+
} // end of class SimpleArg.Holder
89+
90+
.class private auto ansi SimpleArg.Program
91+
extends [mscorlib]System.Object
92+
{
93+
.method private hidebysig static int32
94+
Method(valuetype SimpleArg.MyValue arg) cil managed noinlining
95+
{
96+
// Code size 8 (0x8)
97+
.maxstack 8
98+
IL_0000: ldarga.s arg
99+
IL_0002: ldfld int32 SimpleArg.MyValue::IntValue
100+
IL_0007: ret
101+
} // end of method Program::Method
102+
103+
.method private hidebysig static int32
104+
Main(string[] args) cil managed
105+
{
106+
.entrypoint
107+
// Code size 59 (0x3b)
108+
.maxstack 2
109+
.locals init (int32 V_0)
110+
IL_0000: ldsfld valuetype SimpleArg.MyValue SimpleArg.Holder::RvaStatic
111+
IL_0005: call int32 SimpleArg.Program::Method(valuetype SimpleArg.MyValue)
112+
IL_000a: stloc.0
113+
IL_000b: ldloc.0
114+
IL_000c: ldsfld valuetype SimpleArg.MyValue SimpleArg.Holder::NormalStatic
115+
IL_0011: call int32 SimpleArg.Program::Method(valuetype SimpleArg.MyValue)
116+
IL_0016: add
117+
IL_0017: stloc.0
118+
IL_0018: ldloc.0
119+
IL_0019: ldc.i4.s 100
120+
IL_001b: bne.un.s IL_0029
121+
122+
IL_001d: ldstr "Passed"
123+
IL_0022: call void [mscorlib]System.Console::WriteLine(string)
124+
IL_0027: br.s IL_0039
125+
126+
IL_0029: ldstr "Failed"
127+
IL_002e: call void [mscorlib]System.Console::WriteLine(string)
128+
IL_0033: ldloc.0
129+
IL_0034: call void [mscorlib]System.Console::WriteLine(int32)
130+
IL_0039: ldloc.0
131+
IL_003a: ret
132+
} // end of method Program::Main
133+
134+
.method public hidebysig specialname rtspecialname
135+
instance void .ctor() cil managed
136+
{
137+
// Code size 7 (0x7)
138+
.maxstack 8
139+
IL_0000: ldarg.0
140+
IL_0001: call instance void [mscorlib]System.Object::.ctor()
141+
IL_0006: ret
142+
} // end of method Program::.ctor
143+
144+
} // end of class SimpleArg.Program
145+
146+
.data PreInitValue = bytearray(1F 00 00 00
147+
00 00 00 00
148+
0C 00 00 00 00 00 00 00)
149+
150+
// =============================================================
151+
152+
// *********** DISASSEMBLY COMPLETE ***********************
153+
// WARNING: Created Win32 resource file repro2.res
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
8+
<SchemaVersion>2.0</SchemaVersion>
9+
<ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
10+
<OutputType>Exe</OutputType>
11+
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
12+
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
13+
<RestorePackages>true</RestorePackages>
14+
<CLRTestPriority>1</CLRTestPriority>
15+
</PropertyGroup>
16+
<!-- Default configurations to help VS understand the configurations -->
17+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
18+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
19+
<PropertyGroup>
20+
<DebugType>PdbOnly</DebugType>
21+
<Optimize>True</Optimize>
22+
</PropertyGroup>
23+
<ItemGroup>
24+
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
25+
<Visible>False</Visible>
26+
</CodeAnalysisDependentAssemblyPaths>
27+
</ItemGroup>
28+
<PropertyGroup></PropertyGroup>
29+
<ItemGroup>
30+
<Compile Include="simplearg.il" />
31+
</ItemGroup>
32+
<ItemGroup>
33+
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
34+
</ItemGroup>
35+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
36+
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
37+
</Project>

0 commit comments

Comments
 (0)