From 4d4dce5c75576eccdd3d6fb0105fc2ad457ae67a Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Sat, 11 Jul 2020 10:37:06 -0700 Subject: [PATCH] JIT: retype byrefs passed to unmanaged callers as native int (#39105) Make the jit more robust in cases where the IL producer is passing a byref to an unmanaged caller, by retyping the argument as native int. Allows the jit to produce self-consistent GC info and avoid the issues seen in #34279, at least for byrefs. Closes #39040. --- src/coreclr/src/jit/importer.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 7137acc..10b7607 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -6921,14 +6921,27 @@ void Compiler::impPopArgsForUnmanagedCall(GenTree* call, CORINFO_SIG_INFO* sig) for (GenTreeCall::Use& argUse : GenTreeCall::UseList(args)) { - // We should not be passing gc typed args to an unmanaged call. GenTree* arg = argUse.GetNode(); + call->gtFlags |= arg->gtFlags & GTF_GLOB_EFFECT; + + // We should not be passing gc typed args to an unmanaged call. if (varTypeIsGC(arg->TypeGet())) { - assert(!"*** invalid IL: gc type passed to unmanaged call"); + // Tolerate byrefs by retyping to native int. + // + // This is needed or we'll generate inconsistent GC info + // for this arg at the call site (gc info says byref, + // pinvoke sig says native int). + // + if (arg->TypeGet() == TYP_BYREF) + { + arg->ChangeType(TYP_I_IMPL); + } + else + { + assert(!"*** invalid IL: gc ref passed to unmanaged call"); + } } - - call->gtFlags |= arg->gtFlags & GTF_GLOB_EFFECT; } } -- 2.7.4