Fix catch clauses referring to a generic method argument (#6895)
* Fix catch clauses referring to a generic method argument Scrutinizing the CoreCLR Pri#1 results I found a large bucket of failures caused by mismatched catch clauses for generic exception types. With tons of help from Jan Vorlicek I tracked this down to a subtle difference in getMethodInfo flags. I have added one of the previously failing Pri#1 tests to the CPAOT trivial unit test suite. * Set up the method flags unconditionally per JanK's PR feedback I have audited the corresponding Crossgen code and I must admit Jan Kotas is right as always - the extra method flags should be set no matter whether the R2R build mode is active.
This commit is contained in:
Родитель
00bf204a90
Коммит
67895ecaee
|
@ -394,8 +394,21 @@ namespace Internal.JitInterface
|
|||
methodInfo->maxStack = (uint)methodIL.MaxStack;
|
||||
methodInfo->EHcount = (uint)methodIL.GetExceptionRegions().Length;
|
||||
methodInfo->options = methodIL.IsInitLocals ? CorInfoOptions.CORINFO_OPT_INIT_LOCALS : (CorInfoOptions)0;
|
||||
methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE;
|
||||
|
||||
if (method.AcquiresInstMethodTableFromThis())
|
||||
{
|
||||
methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_THIS;
|
||||
}
|
||||
else if (method.RequiresInstMethodDescArg())
|
||||
{
|
||||
methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODDESC;
|
||||
}
|
||||
else if (method.RequiresInstMethodTableArg())
|
||||
{
|
||||
methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODTABLE;
|
||||
}
|
||||
|
||||
methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE;
|
||||
Get_CORINFO_SIG_INFO(method, &methodInfo->args);
|
||||
Get_CORINFO_SIG_INFO(methodIL.GetLocals(), &methodInfo->locals);
|
||||
|
||||
|
|
|
@ -431,6 +431,84 @@ internal class Program
|
|||
}
|
||||
}
|
||||
|
||||
private class GenException<T> : Exception {}
|
||||
|
||||
private static bool GenericTryCatch<T>()
|
||||
{
|
||||
Exception thrown = new GenException<T>();
|
||||
try
|
||||
{
|
||||
throw thrown;
|
||||
}
|
||||
catch (GenException<T>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Caught {0} (expected {1})", ex.GetType(), thrown.GetType());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class RefX1<T> {}
|
||||
private class RefX2<T,U> {}
|
||||
private struct ValX1<T> {}
|
||||
private struct ValX2<T,U> {}
|
||||
private struct ValX3<T,U,V>{}
|
||||
|
||||
private static bool GenericTryCatchTest()
|
||||
{
|
||||
bool success = true;
|
||||
success = GenericTryCatch<double>() && success;
|
||||
success = GenericTryCatch<string>() && success;
|
||||
success = GenericTryCatch<object>() && success;
|
||||
success = GenericTryCatch<Guid>() && success;
|
||||
|
||||
success = GenericTryCatch<int[]>() && success;
|
||||
success = GenericTryCatch<double[,]>() && success;
|
||||
success = GenericTryCatch<string[][][]>() && success;
|
||||
success = GenericTryCatch<object[,,,]>() && success;
|
||||
success = GenericTryCatch<Guid[][,,,][]>() && success;
|
||||
|
||||
success = GenericTryCatch<RefX1<int>[]>() && success;
|
||||
success = GenericTryCatch<RefX1<double>[,]>() && success;
|
||||
success = GenericTryCatch<RefX1<string>[][][]>() && success;
|
||||
success = GenericTryCatch<RefX1<object>[,,,]>() && success;
|
||||
success = GenericTryCatch<RefX1<Guid>[][,,,][]>() && success;
|
||||
success = GenericTryCatch<RefX2<int,int>[]>() && success;
|
||||
success = GenericTryCatch<RefX2<double,double>[,]>() && success;
|
||||
success = GenericTryCatch<RefX2<string,string>[][][]>() && success;
|
||||
success = GenericTryCatch<RefX2<object,object>[,,,]>() && success;
|
||||
success = GenericTryCatch<RefX2<Guid,Guid>[][,,,][]>() && success;
|
||||
success = GenericTryCatch<ValX1<int>[]>() && success;
|
||||
success = GenericTryCatch<ValX1<double>[,]>() && success;
|
||||
success = GenericTryCatch<ValX1<string>[][][]>() && success;
|
||||
success = GenericTryCatch<ValX1<object>[,,,]>() && success;
|
||||
success = GenericTryCatch<ValX1<Guid>[][,,,][]>() && success;
|
||||
|
||||
success = GenericTryCatch<ValX2<int,int>[]>() && success;
|
||||
success = GenericTryCatch<ValX2<double,double>[,]>() && success;
|
||||
success = GenericTryCatch<ValX2<string,string>[][][]>() && success;
|
||||
success = GenericTryCatch<ValX2<object,object>[,,,]>() && success;
|
||||
success = GenericTryCatch<ValX2<Guid,Guid>[][,,,][]>() && success;
|
||||
|
||||
success = GenericTryCatch<ValX1<int>>() && success;
|
||||
success = GenericTryCatch<ValX1<RefX1<int>>>() && success;
|
||||
success = GenericTryCatch<ValX2<int,string>>() && success;
|
||||
success = GenericTryCatch<ValX3<int,string,Guid>>() && success;
|
||||
|
||||
success = GenericTryCatch<ValX1<ValX1<int>>>() && success;
|
||||
success = GenericTryCatch<ValX1<ValX1<ValX1<string>>>>() && success;
|
||||
success = GenericTryCatch<ValX1<ValX1<ValX1<ValX1<Guid>>>>>() && success;
|
||||
|
||||
success = GenericTryCatch<ValX1<ValX2<int,string>>>() && success;
|
||||
success = GenericTryCatch<ValX2<ValX2<ValX1<int>,ValX3<int,string, ValX1<ValX2<int,string>>>>,ValX2<ValX1<int>,ValX3<int,string, ValX1<ValX2<int,string>>>>>>() && success;
|
||||
success = GenericTryCatch<ValX3<ValX1<int[][,,,]>,ValX2<object[,,,][][],Guid[][][]>,ValX3<double[,,,,,,,,,,],Guid[][][][,,,,][,,,,][][][],string[][][][][][][][][][][]>>>();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private static bool FileStreamNullRefTryCatch()
|
||||
{
|
||||
try
|
||||
|
@ -869,6 +947,7 @@ internal class Program
|
|||
RunTest("EmptyArrayOfString", EmptyArrayOfString());
|
||||
RunTest("EnumerateEmptyArrayOfString", EnumerateEmptyArrayOfString());
|
||||
RunTest("TryCatch", TryCatch());
|
||||
RunTest("GenericTryCatchTest", GenericTryCatchTest());
|
||||
RunTest("FileStreamNullRefTryCatch", FileStreamNullRefTryCatch());
|
||||
RunTest("InstanceMethodTest", InstanceMethodTest());
|
||||
RunTest("ThisObjGenericLookupTest", ThisObjGenericLookupTest());
|
||||
|
|
Загрузка…
Ссылка в новой задаче