[test] Fix dependency on compiler behavior for a couple of tests
authorMarek Habersack <grendel@twistedcode.net>
Wed, 23 Sep 2015 14:24:53 +0000 (16:24 +0200)
committerMarek Habersack <grendel@twistedcode.net>
Wed, 23 Sep 2015 14:24:53 +0000 (16:24 +0200)
A couple of tests for System.Reflection.MethodBody assumed the code generated
by the compiler will be the same as the one generated by Mono's MCS. However,
when the code is built by CSC in release mode (version that comes with VS2015
was tested) the optimizations remove locals required by the old version of the
tests. Also, CSC orders the locals differently to MCS and that breaks one of
the tests which relied on the declaration order.
Another difference is that CSC and MCS type a certain local variable differently.
The variable being a byte* in source code is output in IL as such by MCS, but CSC
outputs an int8& - a by-ref type.
The tests are built by VS but they are executed by Mono on Android and so the
differences come up as errors.
This commit fixes both issues by working around the differences.

Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=33370 when it is included in XA

mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs

index 3650cadc47f3124e3e96f6489ea309d5d16b24ec..3c6e3da2ffb6f74955c01a9e2cca04d2fdeaf55b 100644 (file)
@@ -361,14 +361,20 @@ namespace MonoTests.System.Reflection
 
                        IList<LocalVariableInfo> locals = mb.LocalVariables;
 
-                       // This might break with different compilers etc.
-                       Assert.AreEqual (2, locals.Count, "#3");
-
-                       Assert.IsTrue ((locals [0].LocalType == typeof (byte[])) || (locals [1].LocalType == typeof (byte[])), "#4");
-                       if (locals [0].LocalType == typeof (byte[]))
-                               Assert.AreEqual (false, locals [0].IsPinned, "#5");
-                       else
-                               Assert.AreEqual (false, locals [1].IsPinned, "#6");
+                       bool foundPinnedBytePointer = false;
+                       unsafe {
+                               foreach (LocalVariableInfo lvi in locals) {
+                                       if (lvi.LocalType == typeof (byte[]))
+                                               // This is optimized out by CSC in .NET 4.6
+                                               Assert.IsFalse (lvi.IsPinned, "#3-1");
+
+                                       if (/* mcs */ lvi.LocalType == typeof (byte*) || /* csc */ lvi.LocalType == typeof (byte).MakeByRefType ()) {
+                                               foundPinnedBytePointer = true;
+                                               Assert.IsTrue (lvi.IsPinned, "#3-2");
+                                       }
+                               }
+                       }
+                       Assert.IsTrue (foundPinnedBytePointer, "#4");
                }
 
                public int return_parameter_test ()
@@ -802,21 +808,44 @@ namespace MonoTests.System.Reflection
                        var type = typeof (GenericClass<>).GetMethod("Method").GetMethodBody().LocalVariables[0].LocalType;
                        Assert.AreEqual (typeofT, type);
                        Assert.AreEqual (typeof (GenericClass<>), type.DeclaringType);
+               
+                       bool foundTypeOfK = false;
+                       bool foundExpectedType = false;
+           
+                       MethodBody mb = typeof (GenericClass<>).GetMethod("Method2").GetMethodBody();
+                       foreach (LocalVariableInfo lvi in mb.LocalVariables) {
+                               if (lvi.LocalType == typeofK) {
+                                       foundTypeOfK = true;
+                                       Assert.AreEqual (typeof (GenericClass<>), lvi.LocalType.DeclaringType, "#1-1");
+                               } else if (lvi.LocalType == typeofT) {
+                                       foundExpectedType = true;
+                                       Assert.AreEqual (typeof (GenericClass<>), lvi.LocalType.DeclaringType, "#1-2");
+                               }
+                       }
 
-                       type = typeof (GenericClass<>).GetMethod("Method2").GetMethodBody().LocalVariables[0].LocalType;
-                       Assert.AreEqual (typeofT, type);
-                       Assert.AreEqual (typeof (GenericClass<>), type.DeclaringType);
-
-                       type = typeof (GenericClass<>).GetMethod("Method2").GetMethodBody().LocalVariables[1].LocalType;
-                       Assert.AreEqual (typeofK, type);
-                       Assert.AreEqual (typeof (GenericClass<>), type.DeclaringType);
-
-                       type = typeof (GenericClass<int>).GetMethod("Method2").GetMethodBody().LocalVariables[0].LocalType;
-                       Assert.AreEqual (typeof (int), type);
-
-                       type = typeof (GenericClass<int>).GetMethod("Method2").GetMethodBody().LocalVariables[1].LocalType;
-                       Assert.AreEqual (typeofK, type);
-                       Assert.AreEqual (typeof (GenericClass<>), type.DeclaringType);
+                       Assert.IsTrue (foundTypeOfK, "#1-3");
+                       if (mb.LocalVariables.Count < 2)
+                               Assert.Ignore ("Code built in release mode - 'T var0' optmized out");
+                       else
+                               Assert.IsTrue (foundExpectedType, "#1-4");
+           
+                       foundTypeOfK = false;
+                       foundExpectedType = false;
+                       mb = typeof (GenericClass<int>).GetMethod("Method2").GetMethodBody();
+                       foreach (LocalVariableInfo lvi in mb.LocalVariables) {
+                               if (lvi.LocalType == typeofK) {
+                                       foundTypeOfK = true;
+                                       Assert.AreEqual (typeof (GenericClass<>), lvi.LocalType.DeclaringType, "#2-1");
+                               } else if (lvi.LocalType == typeof (int)) {
+                                       foundExpectedType = true;
+                               }
+                       }
+           
+                       Assert.IsTrue (foundTypeOfK, "#2-3");
+                       if (mb.LocalVariables.Count < 2)
+                               Assert.Ignore ("Code built in release mode - 'int var0' optmized out");
+                       else
+                               Assert.IsTrue (foundExpectedType, "#2-4");
                }
 #endif
        }