Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Arzt <arzt.samuel@live.de>2017-11-11 18:10:56 +0300
committerJan Kotas <jkotas@microsoft.com>2017-11-11 18:10:56 +0300
commit066cfc2708ec4bca52938d6a5267194fe4b90448 (patch)
treeec332b793491f0a43588bfba703db00b343d90f6 /src/ILVerify
parentd605bd5547660d07ff1b0e98ddf9649755c7571a (diff)
[ILVerify] Implement verification of initonly fields (#4914)
* Implemented verification of initonly fields. * Added tests for initonly field verifications.
Diffstat (limited to 'src/ILVerify')
-rw-r--r--src/ILVerify/src/ILImporter.Verify.cs15
-rw-r--r--src/ILVerify/src/Resources/Strings.resx3
-rw-r--r--src/ILVerify/src/VerifierError.cs2
-rw-r--r--src/ILVerify/tests/ILTests/FieldTests.il140
4 files changed, 156 insertions, 4 deletions
diff --git a/src/ILVerify/src/ILImporter.Verify.cs b/src/ILVerify/src/ILImporter.Verify.cs
index e8819dedd..f1eedf754 100644
--- a/src/ILVerify/src/ILImporter.Verify.cs
+++ b/src/ILVerify/src/ILImporter.Verify.cs
@@ -1847,7 +1847,6 @@ again:
var field = ResolveFieldToken(token);
TypeDesc instance;
-
if (isStatic)
{
Check(field.IsStatic, VerifierError.ExpectedStaticField);
@@ -1884,13 +1883,15 @@ again:
bool isPermanentHome = false;
TypeDesc instance;
-
if (isStatic)
{
Check(field.IsStatic, VerifierError.ExpectedStaticField);
isPermanentHome = true;
instance = null;
+
+ if (field.IsInitOnly)
+ Check(_method.IsStaticConstructor && field.OwningType == _method.OwningType, VerifierError.Initonly);
}
else
{
@@ -1910,6 +1911,9 @@ again:
isPermanentHome = actualThis.Kind == StackValueKind.ObjRef || actualThis.IsPermanentHome;
instance = actualThis.Type;
+
+ if (field.IsInitOnly)
+ Check(_method.IsConstructor && field.OwningType == _method.OwningType && actualThis.IsThisPtr, VerifierError.Initonly);
}
Check(_method.OwningType.CanAccess(field, instance), VerifierError.FieldAccess);
@@ -1927,12 +1931,14 @@ again:
var field = ResolveFieldToken(token);
TypeDesc instance;
-
if (isStatic)
{
Check(field.IsStatic, VerifierError.ExpectedStaticField);
instance = null;
+
+ if (field.IsInitOnly)
+ Check(_method.IsStaticConstructor && field.OwningType == _method.OwningType, VerifierError.Initonly);
}
else
{
@@ -1951,6 +1957,9 @@ again:
CheckIsAssignable(actualThis, declaredThis);
instance = actualThis.Type;
+
+ if (field.IsInitOnly)
+ Check(_method.IsConstructor && field.OwningType == _method.OwningType && actualThis.IsThisPtr, VerifierError.Initonly);
}
Check(_method.OwningType.CanAccess(field, instance), VerifierError.FieldAccess);
diff --git a/src/ILVerify/src/Resources/Strings.resx b/src/ILVerify/src/Resources/Strings.resx
index 9e7b84f19..746fea21d 100644
--- a/src/ILVerify/src/Resources/Strings.resx
+++ b/src/ILVerify/src/Resources/Strings.resx
@@ -219,6 +219,9 @@
<data name="InitLocals" xml:space="preserve">
<value>initlocals must be set for verifiable methods with one or more local variables.</value>
</data>
+ <data name="Initonly" xml:space="preserve">
+ <value>Cannot change initonly field outside its .ctor.</value>
+ </data>
<data name="LdftnConstructor" xml:space="preserve">
<value>ldftn/ldvirtftn not allowed on .ctor.</value>
</data>
diff --git a/src/ILVerify/src/VerifierError.cs b/src/ILVerify/src/VerifierError.cs
index 51e4ad689..d1efe85dd 100644
--- a/src/ILVerify/src/VerifierError.cs
+++ b/src/ILVerify/src/VerifierError.cs
@@ -146,7 +146,7 @@ namespace ILVerify
//E_ADDR "Address of not allowed for this item."
//E_ADDR_BYREF "Address of not allowed for ByRef."
//E_ADDR_LITERAL "Address of not allowed for literal field."
- //E_INITONLY "Cannot change initonly field outside its .ctor."
+ Initonly, // Cannot change initonly field outside its .ctor.
//E_WRITE_RVA_STATIC "Cannot modify an imaged based (RVA) static"
//E_THROW "Cannot throw this object."
CallVirtOnValueType, // Callvirt on a value type method.
diff --git a/src/ILVerify/tests/ILTests/FieldTests.il b/src/ILVerify/tests/ILTests/FieldTests.il
new file mode 100644
index 000000000..8780250ae
--- /dev/null
+++ b/src/ILVerify/tests/ILTests/FieldTests.il
@@ -0,0 +1,140 @@
+// 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.Runtime
+{
+}
+
+.assembly FieldTests
+{
+}
+
+.class public auto ansi beforefieldinit FieldTestsType
+ extends [System.Runtime]System.Object
+{
+ .field public initonly int32 InstanceInitonlyField
+ .field public static initonly int32 StaticInitonlyField
+
+ .method public instance void Stfld.InitonlyFieldOutsideCtor_Invalid_Initonly() cil managed
+ {
+ ldarg.0
+ ldc.i4.0
+ stfld int32 FieldTestsType::InstanceInitonlyField
+ ret
+ }
+
+ .method public instance void Ldflda.InitonlyFieldOutsideCtor_Invalid_Initonly() cil managed
+ {
+ ldarg.0
+ ldflda int32 FieldTestsType::InstanceInitonlyField
+ pop
+ ret
+ }
+
+ .method public hidebysig instance void 'special.StoreInitonlyField..ctor_Valid'() cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ldarg.0
+ ldc.i4.0
+ stfld int32 FieldTestsType::InstanceInitonlyField
+ ret
+ }
+
+ .method public hidebysig instance void 'special.LoadAddrInitonlyField..ctor_Valid'(int32) cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .ctor(int32) cil managed
+ {
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ldarg.0
+ ldflda int32 FieldTestsType::InstanceInitonlyField
+ pop
+ ret
+ }
+
+ .method public hidebysig instance void 'special.LoadAddrInitonlyField..ctor_Valid'(int64) cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .ctor(int64) cil managed
+ {
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ldarg.0
+ ldflda int32 FieldTestsType::InstanceInitonlyField
+ pop
+ ret
+ }
+
+ .method public hidebysig instance void 'special.StoreInitonlyFieldOtherType..ctor_Invalid_Initonly'(class OtherType c) cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .ctor(class OtherType c) cil managed
+ {
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ldarg.1
+ ldc.i4.0
+ stfld int32 OtherType::InstanceInitonlyField
+ ret
+ }
+
+ .method public hidebysig instance void 'special.StoreInitonlyFieldOtherInstance..ctor_Invalid_Initonly'(class FieldTestsType c) cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .ctor(class FieldTestsType c) cil managed
+ {
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ldarg.1
+ ldc.i4.0
+ stfld int32 FieldTestsType::InstanceInitonlyField
+ ret
+ }
+
+ .method public hidebysig instance void 'special.StsfldInitonlyInCtor..ctor_Invalid_Initonly'(bool) cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .ctor(bool) cil managed
+ {
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ldc.i4.0
+ stsfld int32 FieldTestsType::StaticInitonlyField
+ ret
+ }
+
+ .method public hidebysig instance void 'special.LdsfldInitonlyInCtor..ctor_Invalid_Initonly'(char) cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .ctor(char) cil managed
+ {
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ldsflda int32 FieldTestsType::StaticInitonlyField
+ pop
+ ret
+ }
+
+ .method public hidebysig instance void 'special.LdsfldStslfdInitonlyCctor..cctor_Valid'() cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .cctor() cil managed
+ {
+ ldsflda int32 FieldTestsType::StaticInitonlyField
+ pop
+ ldc.i4.0
+ stsfld int32 FieldTestsType::StaticInitonlyField
+ ret
+ }
+}
+
+.class public auto ansi beforefieldinit OtherType
+ extends [System.Runtime]System.Object
+{
+ .field public static class OtherType Instance
+
+ .field public initonly int32 InstanceInitonlyField
+ .field public static initonly int32 StaticInitonlyField
+
+ .method public hidebysig instance void 'special.LdfldStlfdInitonlyCctor..cctor_Invalid_Initonly.Initonly'() cil managed { ret }
+ .method public hidebysig specialname rtspecialname instance void .cctor() cil managed
+ {
+ ldsfld class OtherType OtherType::Instance
+ ldflda int32 OtherType::InstanceInitonlyField
+ pop
+ ldsfld class OtherType OtherType::Instance
+ ldc.i4.0
+ stfld int32 OtherType::InstanceInitonlyField
+ ret
+ }
+}