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

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kliger <alklig@microsoft.com>2017-12-19 00:55:18 +0300
committerAleksey Kliger (λgeek) <akliger@gmail.com>2018-01-02 20:05:48 +0300
commit6102b9538555180cea57b92c3969d324cedf2f7f (patch)
tree663ec036319e821039fec8c298130faa6fd2d07d /mcs/class/corlib
parentaf165436b5a1feaee945046b99fbdcdd93a84534 (diff)
[tests] SRE check that a memberref token is emitted for a gtd
Regression test for https://github.com/mono/mono/issues/6192
Diffstat (limited to 'mcs/class/corlib')
-rw-r--r--mcs/class/corlib/Test/System.Reflection.Emit/ILGeneratorTest.cs6
-rw-r--r--mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs123
2 files changed, 126 insertions, 3 deletions
diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/ILGeneratorTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/ILGeneratorTest.cs
index b31ed2e117e..07b8032c6c3 100644
--- a/mcs/class/corlib/Test/System.Reflection.Emit/ILGeneratorTest.cs
+++ b/mcs/class/corlib/Test/System.Reflection.Emit/ILGeneratorTest.cs
@@ -19,6 +19,7 @@ namespace MonoTests.System.Reflection.Emit
[TestFixture]
public class ILGeneratorTest
{
+ ModuleBuilder modulebuilder;
TypeBuilder tb;
ILGenerator il_gen;
@@ -38,8 +39,8 @@ namespace MonoTests.System.Reflection.Emit
AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
assemblyName, AssemblyBuilderAccess.Run);
- ModuleBuilder module = assembly.DefineDynamicModule ("module1");
- tb = module.DefineType ("T", TypeAttributes.Public);
+ modulebuilder = assembly.DefineDynamicModule ("module1");
+ tb = modulebuilder.DefineType ("T", TypeAttributes.Public);
}
[Test]
@@ -610,6 +611,5 @@ namespace MonoTests.System.Reflection.Emit
Assert.AreEqual ("1", s);
}
-
}
}
diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
index c1ae91971f9..807a1dd3e95 100644
--- a/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
+++ b/mcs/class/corlib/Test/System.Reflection.Emit/ModuleBuilderTest.cs
@@ -1062,5 +1062,128 @@ namespace MonoTests.System.Reflection.Emit
Assert.AreEqual (0, module.MetadataToken);
}
+ [Test]
+ public void SaveMemberRefGtd () {
+ // Ensure that the a memberref token is emitted for a
+ // field or for a method of a gtd in the same dynamic assembly.
+ // Regression test for GitHub #6192
+
+ // class T {
+ // public string F () {
+ // int i = new C<int>().Foo (42).field1;
+ // return i.ToString();
+ // }
+ // public string F2 () {
+ // int i = new C<int>().Bar (42);
+ // return i.ToString ();
+ // }
+ // }
+ // class C<X> {
+ // public X field1;
+ // public C<X> Foo (X x) {
+ // this.field1 = x;
+ // return this;
+ // }
+ // public X Bar (X x) {
+ // return this.Foo (x).field1;
+ // }
+ //}
+
+ AssemblyName an = genAssemblyName ();
+ AssemblyBuilder ab = Thread.GetDomain ().DefineDynamicAssembly (an, AssemblyBuilderAccess.RunAndSave, tempDir);
+ ModuleBuilder modulebuilder = ab.DefineDynamicModule (an.Name, an.Name + ".dll");
+
+ var tb = modulebuilder.DefineType ("T", TypeAttributes.Public);
+ var il_gen = tb.DefineMethod ("F", MethodAttributes.Public, typeof(string), null).GetILGenerator ();
+ var il_gen2 = tb.DefineMethod ("F2", MethodAttributes.Public, typeof(string), null).GetILGenerator ();
+
+ var cbuilder = modulebuilder.DefineType ("C", TypeAttributes.Public);
+ var genericParams = cbuilder.DefineGenericParameters ("X");
+
+ var field1builder = cbuilder.DefineField ("field1", genericParams[0], FieldAttributes.Public);
+
+ var cOfX = cbuilder.MakeGenericType(genericParams);
+
+ var fooBuilder = cbuilder.DefineMethod ("Foo",
+ MethodAttributes.Public,
+ cOfX,
+ new Type [] { genericParams[0] });
+ var cdefaultCtor = cbuilder.DefineDefaultConstructor (MethodAttributes.Public);
+
+ var fooIL = fooBuilder.GetILGenerator ();
+
+ fooIL.Emit (OpCodes.Ldarg_0);
+ fooIL.Emit (OpCodes.Ldarg_1);
+ // Emit (Stfld, field1builder) must generate a memberref token, not fielddef.
+ fooIL.Emit (OpCodes.Stfld, field1builder);
+ fooIL.Emit (OpCodes.Ldarg_0);
+ fooIL.Emit (OpCodes.Ret);
+
+ var barBuilder = cbuilder.DefineMethod ("Bar",
+ MethodAttributes.Public,
+ genericParams [0],
+ new Type [] { genericParams [0] });
+ var barIL = barBuilder.GetILGenerator ();
+
+ barIL.Emit (OpCodes.Ldarg_0);
+ barIL.Emit (OpCodes.Ldarg_1);
+ // Emit (Call, fooBuilder) must generate a memberref token, not a methoddef.
+ barIL.Emit (OpCodes.Call, fooBuilder);
+ barIL.Emit (OpCodes.Ldfld, field1builder);
+ barIL.Emit (OpCodes.Ret);
+
+ var cOfInt32 = cbuilder.MakeGenericType (new Type [] { typeof (int) });
+ var fooOfInt32 = TypeBuilder.GetMethod (cOfInt32, fooBuilder);
+ var cfield1OfInt32 = TypeBuilder.GetField (cOfInt32, field1builder);
+ var intToString = typeof(int).GetMethod ("ToString", Type.EmptyTypes);
+
+ var ilocal = il_gen.DeclareLocal (typeof(int));
+ il_gen.Emit (OpCodes.Newobj, TypeBuilder.GetConstructor (cOfInt32, cdefaultCtor));
+ il_gen.Emit (OpCodes.Ldc_I4, 42);
+ il_gen.Emit (OpCodes.Call, fooOfInt32);
+ il_gen.Emit (OpCodes.Ldfld, cfield1OfInt32);
+ il_gen.Emit (OpCodes.Stloc, ilocal);
+ il_gen.Emit (OpCodes.Ldloca, ilocal);
+ il_gen.Emit (OpCodes.Call, intToString);
+ il_gen.Emit (OpCodes.Ret);
+
+
+ var i2local = il_gen2.DeclareLocal (typeof (int));
+ var barOfInt32 = TypeBuilder.GetMethod (cOfInt32, barBuilder);
+ il_gen2.Emit (OpCodes.Newobj, TypeBuilder.GetConstructor (cOfInt32, cdefaultCtor));
+ il_gen2.Emit (OpCodes.Ldc_I4, 17);
+ il_gen2.Emit (OpCodes.Call, barOfInt32);
+ il_gen2.Emit (OpCodes.Stloc, i2local);
+ il_gen2.Emit (OpCodes.Ldloca, i2local);
+ il_gen2.Emit (OpCodes.Call, intToString);
+ il_gen2.Emit (OpCodes.Ret);
+
+ cbuilder.CreateType ();
+ tb.CreateType ();
+
+ ab.Save (an.Name + ".dll");
+
+ /* Yes the test really needs to roundtrip through SRE.Save().
+ * The regression is in the token fixup code on the saving codepath.
+ */
+
+ var assm = Assembly.LoadFrom (Path.Combine (tempDir, an.Name + ".dll"));
+
+ var baked = assm.GetType ("T");
+
+ var x = Activator.CreateInstance (baked);
+ var m = baked.GetMethod ("F");
+
+ var s = m.Invoke (x, null);
+
+ Assert.AreEqual ("42", s);
+
+ var m2 = baked.GetMethod ("F2");
+
+ var s2 = m2.Invoke (x, null);
+
+ Assert.AreEqual ("17", s2);
+ }
+
}
}